【问题标题】:How to use grep match string then look for other string如何使用 grep 匹配字符串然后查找其他字符串
【发布时间】:2016-04-28 14:43:49
【问题描述】:

是否可以查找'string1',如果它为真,然后使用grep 查找'string2'。 这是我的情况。我有很多 txt 报告文件,我需要根据测试路径“测试路径:路径/到/测试”搜索“失败” 示例报告文件:

     Test path:          path/to_tests/t1 
     Host name:                   testpc1
                  AMEND_1/Sec3/E30012.c,          ;               PASS;     ;              ;             ;          ;
                  AMEND_1/Sec3/E30013.c,          ;               FAIL;     ;              ;             ;          ;
                  AMEND_1/Sec3/E30014.c,          ;               PASS;     ;              ;             ;          ;
                  AMEND_1/Sec3/E30015.c,          ;               FAIL;     ;              ;             ;          ;

我正在尝试执行以下命令,但它只打印 FAIL 行而不是测试路径,我也想删除 ';'在行中。

 find . -name "*concat.txt" | xargs grep -E 'Test path: path/to_tests/t1' grep -e 'FAIL'

请指导我如何使用一行命令来实现这一点。

希望输出:

 Test path:          path/to_tests/t1   AMEND_1/Sec3/E30013.c  FAIL
 Test path:          path/to_tests/t1   AMEND_1/Sec3/E30015.c  FAIL

【问题讨论】:

  • 请添加您想要的输出。
  • 在单行命令中?为什么这很重要?它有多重要?
  • 我们有处理报告比较和excel生成的大shell脚本。所以想在开始比较之前添加一行命令。所以想要将失败重定向到文件并发送给团队,团队成员只查找失败的测试会很有用。
  • 好的,但到目前为止,我还没有听到任何理由说明为什么它需要是单个命令...
  • 我不想弄乱 shell 脚本,因为我不是 shell 脚本专家。所以计划有一个行命令,这样我就可以在它开始生成 excel 之前将它放在 shell 脚本中。

标签: regex perl shell grep


【解决方案1】:

简单的 awk。

awk '/Test path:/ { t=$0; next }
    $3 == "FAIL;" ( print t, $2, $3 }' **/*concat.txt

如果您的 shell 太旧而无法支持 ** 通配符,或者您在该通配符上确实有非普通文件的匹配项,您可能希望保留您的 find 命令,并将其通过管道传递给 Awk。

这将保留FAIL 之后的分号。如果这是一个问题,在打印之前很容易摆脱; sub(";", "", $3):

第一行的正则表达式只是寻找“测试路径:”——如果你想寻找一个特定的路径,你需要转义反斜杠。

【讨论】:

  • 谢谢三胞胎,它工作得很好。我会尝试在 shell 脚本中插入这一行。
【解决方案2】:

使用这个:

find . -name "*concat.txt" | (read file && egrep 'Test path:[ \t]*path/to_tests/t1' $file && grep 'FAIL' $file)

我不确定Test path; (...) 行中的空格,所以我添加了模式[ \t]* 以匹配您可能在其中遇到的任何空格。

这将打印:

Test path: (whitespace) path/to_tests/t1   
AMEND_1/Sec3/E30013.c,          ;               FAIL;     ;
AMEND_1/Sec3/E30015.c,          ;               FAIL;     ;

如果您确实需要问题中所述的输出,则需要不止一行,才能雄辩地完成,并且可能需要使用其他命令,例如 sedawkperl regexps。

带有一些sed 的版本以更好地格式化输出。

find . -name "*concat.txt" | (read file && egrep 'Test path:[ \t]*path/to_tests/t1' $file | sed 's/^[ \t]*//' && grep 'FAIL' $file | sed 's/^[ \t]*//' | sed 's/[ \t]*;[ \t]*//' | sed 's/,\(FAIL\).*/ \1/')

【讨论】:

  • 它没有像上面显示的那样打印,它只打印Test path: (whitespace) path/to_tests/t1,并且光标不会退出执行模式。
  • 很少需要通过管道将sed 传递到sed。您需要将其重构为单个 sed 脚本,可能还会考虑到 grep。见iki.fi/era/unix/award.html#grep
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多