【问题标题】:Capture sub-string at different positions from command's output从命令的输出中捕获不同位置的子字符串
【发布时间】:2023-03-31 01:44:01
【问题描述】:

我有一个要求,我必须从命令的输出中捕获一个字符串并将其存储起来以供进一步处理。问题是命令的输出有时可能会发生变化,因此会导致错误的结果。


请求的数据集看起来像

application_1532934978357_3376 app_name job_type user any_name_2 RUNNING 
UNDEFINED 10% hostname
application_1532934978357_3375 app_name job_type user any_name_2 RUNNING 
UNDEFINED 10% hostname
application_1532934978357_3374 app_name job_type user any_name_2 RUNNING 
UNDEFINED 10% hostname
application_1532934978357_249069 some_information_etc job_type any_name_2 
RUNNING UNDEFINED 95% hostname
application_1532934978357_239728 app_name job_type any_name_2 RUNNING 
UNDEFINED 10% hostname
application_1532934978357_89483 some_info job_type user any_name RUNNING 
UNDEFINED 10% hostname
application_1532934978357_248180 with prog_vrsn as
(se...select cast(Stage-27) job_type user any_name RUNNING UNDEFINED 36.1% 
hostname
application_15329349783879_657880 select cast
value ..(stage35) with table
where value=5; job_type user any_name RUNNING UNDEFINED 10% hostname

我使用:

cat in | grep "RUNNING" | grep "any_name" | awk '{print $1}'

生成输出为

application_1532934978357_89483 
(se...select cast(Stage-27)
where

虽然我想将输出生成为:

application_1532934978357_89483 
application_1532934978357_248180 
application_15329349783879_657880 

【问题讨论】:

  • 始终建议您将样品包装在 CODE TAGS {} 按钮中。

标签: bash shell awk grep


【解决方案1】:

这是一个 GNU awk 脚本,它只捕获与单词 any_name 关联的 application_XXXX

awk -v RS='[ \n]' '/application_[0-9_]+/{a=$0}/\<any_name\>/{print a}' file

它依赖于设置为捕获每个单词的记录分隔符RSapplication_XXXX 字符串存储在变量a 中,并在找到单​​词any_name 时打印出来。

【讨论】:

  • 感谢您编辑并尝试解决问题。
  • 虽然当我在上面尝试时,它只是给了我/打印了 id_tag 值。添加更多信息。 app_id -> 实际上看起来像:app_xxxx_xxx(x=整数)。 id_tag 看起来像:some.string_srting.string。行由“\n”分隔,字段由空格分隔。感谢您的帮助。
  • @cod_enthu 请使用包含您所描述用例的示例更新您的问题。也请给出预期的输出。不幸的是,对于给定的示例,我无法提供更多帮助。
  • 我现在已经更新了有问题的数据集和预期输出。
  • @Cod_enthu 如果是这样,只需将第二个条件更改为/\&lt;any_name\&gt;|\&lt;any_other_word\&gt;//\&lt;any_name_?2?\&gt;/
【解决方案2】:

您只需要在命令中再添加一个 grep:

command's output | grep "status_run" | grep -e "id_tag1" -e "id_tag2" | grep "app_id" | awk '{print $1}'

awk '(/status_run/) &amp;&amp; (/app_id*/) &amp;&amp; (/id_tag[12]/) {print $1;}' filename

这只会打印所有带有 id_tag1 和 id_tag2 并且其中包含“status_run”的 app_id。


更新问题后的解决方案:

cat filename | grep "RUNNING" | grep "any_name" | grep "application*" | awk '{print $1}'

如果要打印所有应用程序 ID,请使用以下命令:

awk '/application*/{print $1}' filename

【讨论】:

  • 所有的代码都应该重构为一个单独的 Awk 脚本。
  • @tripleee 我想@oliv 已经回答了。他缺少status_run 部分。
  • You just need to add one more grep - 这很有趣:-)。 awk '/foo/' file | awk '{print $1}' = awk '/foo/{print $1}' file.
  • 另外 awk 使用真正的正则表达式而不是 glob 模式; /app_id*/ 匹配任何 app_i app_id app_idd app_idddddddd 等。您可能指的是 /app_id.*/app_id 后跟任何字符),但您不需要 .*,因为 awk 匹配默认情况下是未锚定的。
  • @Ashutosh 更新的命令/解决方案也将丢失应用程序 ID:application_1532934978357_248180 application_15329349783879_657880
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 2020-05-19
  • 2014-08-31
  • 2013-11-06
  • 2012-11-22
  • 1970-01-01
相关资源
最近更新 更多