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,失败原因:
您可以尝试处理 awk
的 RS
和 FS
变量以使解析更容易:
$ 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
我正在尝试使用 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,失败原因:
您可以尝试处理 awk
的 RS
和 FS
变量以使解析更容易:
$ 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