仍在与混乱的日志文件作斗争。我想要的是找到首先匹配字符串 X 然后匹配字符串 Y 的行。然后我想将它们一起打印。问题是,有时有X,但没有Y。
输入示例
31 X
32 Y
33 X
34 Y
35 X
36 X
37 Y
38 X
39 X
预期产出
31 X
32 Y
33 X
34 Y
36 X
37 Y
因此,第 35、38 和 39 行被省略,因为没有字符串 Y。
我的出发点是这样的:
cat $filename | grep -E X\|Y | grep -A1 'X'
但这并没有过滤掉第 35、38 和 39 行。我想要的是一个条件:如果有 Y,则仅打印 X 行,然后打印 Y 行。如果没有,则不打印任何内容。
答案1
使用sed
:
sed -n ':b /X/ { h; n; /Y/! b b; H; x; p; }'
输出:
31 X
32 Y
33 X
34 Y
36 X
37 Y
答案2
其他sed
:
$ sed -e '/X/{
$!N
/\n.*Y/!D
}' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
答案3
有多种工具可以做到这一点。如果你有pcregrep
(它应该在你的发行版的存储库中可用),你可以这样做:
$ pcregrep -M 'X\n[^\n]+Y' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
该-M
开关允许模式匹配换行符,并且正则表达式匹配X
,后跟换行符,然后是任何非换行符和Y
。
另一种选择是编写一个小脚本,如果上一行匹配,则保存上一行,如果X
当前行匹配,则将其与当前行一起打印Y
。例如,在awk
:
$ awk '{if(last~/X/ && /Y/){print last"\n"$0}last=$0}' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
或者 Perl:
$ perl -ne '$last=~/X/ && /Y/ && print "$last$_"; $last=$_' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
答案4
由于问题被标记为awk
:
$ awk 'p2 == "X" && $2 == "Y" { print p; print } { p = $0; p2 = $2 }' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
这将打印一行X
和紧随其后的Y
一行(如果有的话)(或者两者都不会被打印)。
变量p
和p2
分别保存未修改的前一行及其第二列。