简体   繁体   English

在使用BASH匹配字符串后,在文件中进行正向和反向搜索

[英]Forward and reverse search in file after matching string with BASH

I have a large file that consists of tests run sequentially. 我有一个大型文件,包含按顺序运行的测试。 Each test has a test name and test data. 每个测试都有一个测试名称和测试数据。 I want filter out all tests that failed into a separate file. 我想过滤掉所有失败的测试到一个单独的文件中。 - The test names are enclosed in square brackets. - 测试名称括在方括号中。 - The test data in the example below are the 4 lines in each test - If a test fails it will have the keyword FAILED in it. - 以下示例中的测试数据是每个测试中的4行 - 如果测试失败,则其中将包含关键字FAILED。 Here is a simple example: 这是一个简单的例子:

[CPU]
aaaa
bbbb
cccc
[Drives]
dddd
FAILED eeee
ffff
[Memory]
gggg
hhhh
iiii
[Power]
FAILED jjjj
FAILED kkkk
llll
[Graphics]
mmmm
nnnn
oooo

In this example 2 of the 5 tests failed so the output file would be: 在这个例子中,5个测试中有2个失败,因此输出文件将是:

[Drives]
dddd
FAILED eeee
ffff
[Power]
FAILED jjjj
FAILED kkkk
llll

Using BASH I can use grep to find the failed lines but I don't know how I can extract the full tests including the test names. 使用BASH我可以使用grep来查找失败的行,但我不知道如何提取包括测试名称在内的完整测试。 I was thinking that after finding a match with grep I would use a do while loop and output each line to the file until it finds the [] above and below it. 我想在找到与grep的匹配后,我会使用do while循环并将每行输出到文件,直到它找到[]上方和下方的[]。

You can also use sed command 您也可以使用sed命令

sed ':a;N;/\[.*\]$/{/.*FAILED.*\n/{P;D};D;t};s/\n/-/g;$d;t a;' file_name | sed 's/-/\n/g'

Explanation: 说明:

N   -- Get the two line and store in the pattern space . 
t a -- continue the loop and append the line to the pattern space 
P   -- Print the first line in the pattern space .
D   -- Delete the first line in the pattern space .

Execution way: 执行方式:

N get the two line and t loop append each line into the pattern space until the next block of header. N得到两行和t loop将每一行追加到模式空间中,直到下一个标题块。 After the header all the lines are considered as a single line by using substitution. 在标题之后,通过使用替换将所有行视为单行。 Then some validation is performed like if FAILED pattern is found then print the until newline is found and delete it, else delete the line until newline, then continue the process. 然后执行一些验证,如果找到FAILED模式然后打印直到找到换行并删除它,否则删除该行直到换行,然后继续该过程。 Finished all the process then substitute the every field with newline. 完成所有过程然后用换行符替换每个字段。

The first thing that comes to my mind is very ugly solution with temporary files: 我想到的第一件事就是使用临时文件非常难看的解决方案:

split -l 4 --additional-suffix=.txt yourfile.txt tmpfile; grep -C 4 FAILED tmpfile*.txt

It is definitely not most efficient but could be useful especially if (as you wrote) you want to store failed output in separate files anyway. 它绝对不是最有效的,但如果(如你所写)你想要将失败的输出存储在单独的文件中,它可能会很有用。

Using GNU awk: 使用GNU awk:

gawk -v RS='\\[[^\\]]+\\]' /FAILED/ { printf "%s%s", p, $0 } { p = RT }' file

Output: 输出:

[Drives]
dddd
FAILED eeee
ffff
[Power]
FAILED jjjj
FAILED kkkk
llll

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM