SED 提取 2 个模式匹配后的第一次出现

SED extract first occurance after 2 patterns match

我正在尝试使用 c-shell(恐怕其他选项不可用)和 SED 来解决这个问题。给定此示例文件,其中包含所有失败测试的报告:

============
test_085
============
- Signature code: F2B0C
- Failure reason: timeout
- Error: test has timed out

============
test_102
============
- Signature code: B4B4A
- Failure reason: syntax
- Error: Syntax error on file example.c at line 245

============
test_435
============
- Signature code: 000FC0
- Failure reason: timeout
- Error: test has timed out   

我有一个脚本循环遍历我 运行 的所有测试,我根据此报告检查它们是否失败并稍后进行一些统计:

if (`grep -c $test_name $test_report` > 0) then
  printf ",TEST FAILED" >>! $report
else
  printf ",TEST PASSED" >>! $report
endif

如果在$test_report中找到$test_name,我想提取原因。例如 test_085 我只想提取 'timeout',test_102 只提取 'syntax',test_435 'timeout',test_045 不会是这样,因为在这个报告中没有找到(意味着它已经通过了)。本质上我想提取这两个模式匹配后的第一次出现:test_085,失败原因:

您可以尝试处理 awkRSFS 变量以使解析更容易:

$  awk -v RS='' -F='==*' '{gsub(/\n/," ")
    sub(/.*Failure reason:/,"",)
    sub(/- Error:.*/,"",)
    printf "%s : %s\n",,}' file

输出:

 test_085  :  timeout
 test_102  :  syntax
 test_435  :  timeout

如果您不关心换行符,可以删除 gsub() 功能。

为指定的测试名称提取“失败原因” - 简短awk方法:

awk -v t_name="test_102" '==t_name{ f=1 }f && /Failure reason/{ print ; exit }' reportfile
  • ==t_name{ f=1 } - 在遇到与模式匹配的行时(即 测试名称 t_name) - 设置标志 f进入活动状态

  • f && /Failure reason/ - 在遍历考虑 test name 部分的行时(而 f 是 "active") - 捕获带有 Failure reason 的行并打印第 4 个字段中的原因

  • exit - 立即退出脚本执行以避免冗余处理


输出:

syntax

每当您的输入具有名称到值映射的属性时,最好的方法是首先创建一个数组来捕获下面的那些映射 (n2v[]),然后通过名称访问这些值.例如:

$ cat tst.awk
BEGIN { RS=""; FS="\n" }
 == id {
    for (i=4; i<=NF; i++) {
        name = value = $i
        gsub(/^- |:.*$/,"",name)
        gsub(/^[^:]+: /,"",value)
        n2v[name] = value
    }
    print n2v[attr]
}

$ awk -v id='test_085' -v attr='Failure reason' -f tst.awk file
timeout

$ awk -v id='test_085' -v attr='Error' -f tst.awk file
test has timed out

$ awk -v id='test_102' -v attr='Signature code' -f tst.awk file
B4B4A

$ awk -v id='test_102' -v attr='Error' -f tst.awk file
Syntax error on file example.c at line 245

$ awk -v id='test_102' -v attr='Failure reason' -f tst.awk file
syntax