【问题标题】:Shell script to retrieve the status of objects from the given output用于从给定输出中检索对象状态的 Shell 脚本
【发布时间】:2014-09-23 03:55:36
【问题描述】:

我正在尝试使用 shell 脚本从以下输出中检索对象的状态(Name 字段的值和 OpState 字段的值对应相同)。例如在上面的输出中的状态“DP-UID-FSH”的“向上”。我想产生如下输出:

平台:Solaris 上的 Bash。

DP-UID-FSH is up.
DP-Cert-FSH is up.

以下是需要解析以产生上述输出的文件内容。

<ConfigState>saved</ConfigState></ObjectStatus><ObjectStatus xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<Class>HTTPSSourceProtocolHandler</Class>
<OpState>up</OpState>
<AdminState>enabled</AdminState>
<Name>DP-UID-FSH</Name>
<EventCode>0x00000000</EventCode>
<ErrorCode/>
<ConfigState>saved</ConfigState></ObjectStatus><ObjectStatus xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<Class>SLMAction</Class>
<OpState>up</OpState>
<AdminState>enabled</AdminState>
<Name>DP-Cert-FSH</Name>
<EventCode>0x00000000</EventCode>
<ErrorCode/>
<ConfigState>saved</ConfigState></ObjectStatus><ObjectStatus     xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<Class>SLMAction</Class>
<OpState>up</OpState>
<AdminState>enabled</AdminState>
<Name>shape</Name>
<EventCode>0x00000000</EventCode>
<ErrorCode/>

保存

我是 shell 脚本的新手,不知道如何实现这一点?

【问题讨论】:

标签: bash perl shell awk solaris


【解决方案1】:

Awk 解决方案变得混乱,所以我只添加另一个使用 Perl 的答案。我不精通 Perl,但我学起来很容易,这也可以解决它:

perl -lane '$state = (split(/[<>]/))[2] if /OpState/; print ((split(/[<>]/))[2] . " is $state.") if /<Name>/' file

输出:

DP-UID-FSH is up.
DP-Cert-FSH is up.
shape is up.

作为jaypal suggested(谢谢),由于启用了自动拆分(-a),因此不需要拆分:

perl -F'[<>]' -lane '$state = $F[2] if /OpState/; print "$F[2] is $state" if /<Name>/' file

【讨论】:

  • 它就像一个魅力。你能简要解释一下这个脚本的工作原理吗?
  • 它只处理包含&lt;OpState&gt;&lt;Name&gt; 的行。当它找到&lt;OpState&gt; 时,它会提取该值并将其保存到一个变量($state)中。接下来它应该找到&lt;Name&gt;,当它找到它时,它将提取其中的值,同时与$state一起打印消息。
  • 你能解释一下(split(/[&lt;&gt;]/))[2]吗?是匹配 的正则表达式吗?
  • 这是有据可查的here。它使用与/[&lt;&gt;]/&lt;&gt;)匹配的分隔符将行($_)拆分为一个数组。 [2] 指向运行命令后提取的第三个元素。
  • @konsolebox -a 选项适用于autosplit,所以它在这里并没有真正做任何事情,因为您稍后手动拆分行。替代方案是perl -F'[&lt;&gt;]' -lane '$state = $F[2] if /OpState/; print "$F[2] is $state" if /&lt;Name&gt;/' file。 +1 因为我一直很欣赏perl 解决方案。 :).
【解决方案2】:

使用 GNU Awk 或 Mawk:

awk -v RS='<OpState>' -F '[<>]' 'NR > 1 { printf "%s is %s.\n", $9, $1 }' file

另一个:

awk '/OpState/ { gsub(/<\/?OpState>/, ""); s = $0; } /<Name>/ { gsub(/<\/?Name>/, ""); printf "%s is %s.\n", $0, s; }' file

还有一个:

awk -F '[<>]' '/OpState/ { s = $3; } /<Name>/ { printf "%s is %s.\n", $3, s; }' file

输出:

DP-UID-FSH is up.
DP-Cert-FSH is up.
shape is up.

【讨论】:

  • 我在使用这个时遇到语法错误。我在 Solaris 上的 BASH shell 中运行它。 awk: syntax error near line 1 awk: bailing out near line 1
  • @user2607367 你能告诉我你的awk版本吗? awk --version
  • 可能是 Nawk。不幸的是,我的脚本与它不兼容。如果您可以将 Gawk 或 Mawk 安装到您的系统中,您将能够使其工作。
  • awk --version 没有产生任何输出
  • @user2607367 既不是 Gawk 也不是 Mawk。
猜你喜欢
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 2021-09-18
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多