grep 3 最近发生的事件和发生的一些行
grep 3 latest occurences and some lines around the occurence
我有一个这样的文件:
exception: anythinggggg...
exception: anythinggggg...
abchdhjsdhsd
ygsuhesnkc
exception: anythingggg...
exception: anything...
..
..
我想 grep 最近两次出现的 exception 关键字及其前 3 行和后 3 行。
我正在使用类似
的东西
grep -C 3 exception | tail -12
我在这里使用 tail -12,因为我希望每次出现 6 行,最近出现 2 行。当出现的异常彼此相距很远时,这很好用,但如果说两次出现都是连续的,则给我无用的行。
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
exception
exception
exception
abcd
在上面的例子中,它给了我
abdgjsd
abdgjsd
abdgjsd
exception
exception
exception
abcd
然而,我想要的是
abdgjsd
exception
exception -----------------> OUTPUT FOR FIRST OCCURRENCE
exception
abcd
abdgjsd
abdgjsd
exception-----------------> OUTPUT FOR SECOND OCCURRENCE
exception
exception
abcd
还有其他方法吗?可能是我还可以指定出现次数的东西,而不仅仅是 grep 行和尾部它的一些输出。
您得到的输出是因为 grep
在下一场比赛中停止打印上下文 (-C
)。我不知道如何让它表现得不一样。
下面的脚本(写在命令行上)读取整个文件并形成一个行数组。然后它遍历它并为每个匹配项打印周围的两行,或者最多 start/end 个数组。
perl -MList::Util=min,max -0777 -wnE'
@m = split /\n/;
for (0..$#m) {
if ($m[$_] =~ /exception/) {
$bi = max(0,$_-2);
$ei = min($_+2, $#m);
say for @m[$bi..$ei];
say "---"
}
}
' input.txt
打印 ---
以便于查看输出。这将打印所需的输出。
-0777
选项使它 slurp 整个文件到 $_
变量中,换行符是 split
。迭代遍历数组索引($#m
是 @m
的最后一个元素的索引)。 $bi
和 $ei
是要打印的 begin/end 索引,在数组的开头和结尾附近不能是 +/- 2。
输出可以通过管道传输到 tail
,但这不能自动进行:如果匹配在最后两行内,则输出行将减少(一两行),因此需要输入以精确切断而闻名。或者在脚本中找到匹配索引,@idx = grep { $m[$_] =~ /exception/} for 0..$#m;
,并在条件中使用它来只打印最后两个。
如果您要使用这样的东西,我会把它做成一个脚本。然后直接将所有行读入数组,提供命令行选项(如grep
中的-C
)等
维护逐行处理会使工作复杂得多。我们需要跟踪匹配项,以便我们可以在阅读后打印以下行。但是这里我们需要 多个 这样的记录——对于下一个匹配项,如果它们出现在要打印的以下行中。
这是一个开始:
$ cat tst.awk
BEGIN { bufSize = 5 }
{ updBuf(NR) }
/exception/ { rangeEndNrs[NR+int(bufSize/2)] }
NR in rangeEndNrs { prtBuf(NR) }
END { prtBuf(NR+1) }
function updBuf(nr) {
buf[((nr-1)%bufSize)+1] = [=10=]
}
function prtBuf(nr, i) {
for (i=1; i<=bufSize; i++) {
print buf[((nr+i-1)%bufSize)+1]
}
print "---"
}
.
$ awk -f tst.awk file
abdgjsd
abdgjsd
exception
exception
exception
---
abdgjsd
exception
exception
exception
abcd
---
exception
exception
exception
abcd
abdgjsd
---
它的工作原理是只保留一个 5 行的输入行缓冲区,并且在任何地方找到 "exception" 设置一个指示器,指示 2 行后缓冲区应该被打印,从而打印 "exception" 行加上前后两行。你只需要按摩它来处理 "exception" 发生在输入文件开头或结尾不到 2 行的情况,但是你想要处理它(看看上面的最后一个输出块是如何环绕的,大概是不受欢迎的缓冲区,因为它 运行 离开输入文件的末尾)。
我有一个这样的文件:
exception: anythinggggg...
exception: anythinggggg...
abchdhjsdhsd
ygsuhesnkc
exception: anythingggg...
exception: anything...
..
..
我想 grep 最近两次出现的 exception 关键字及其前 3 行和后 3 行。
我正在使用类似
的东西grep -C 3 exception | tail -12
我在这里使用 tail -12,因为我希望每次出现 6 行,最近出现 2 行。当出现的异常彼此相距很远时,这很好用,但如果说两次出现都是连续的,则给我无用的行。
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
exception
exception
exception
abcd
在上面的例子中,它给了我
abdgjsd
abdgjsd
abdgjsd
exception
exception
exception
abcd
然而,我想要的是
abdgjsd
exception
exception -----------------> OUTPUT FOR FIRST OCCURRENCE
exception
abcd
abdgjsd
abdgjsd
exception-----------------> OUTPUT FOR SECOND OCCURRENCE
exception
exception
abcd
还有其他方法吗?可能是我还可以指定出现次数的东西,而不仅仅是 grep 行和尾部它的一些输出。
您得到的输出是因为 grep
在下一场比赛中停止打印上下文 (-C
)。我不知道如何让它表现得不一样。
下面的脚本(写在命令行上)读取整个文件并形成一个行数组。然后它遍历它并为每个匹配项打印周围的两行,或者最多 start/end 个数组。
perl -MList::Util=min,max -0777 -wnE'
@m = split /\n/;
for (0..$#m) {
if ($m[$_] =~ /exception/) {
$bi = max(0,$_-2);
$ei = min($_+2, $#m);
say for @m[$bi..$ei];
say "---"
}
}
' input.txt
打印 ---
以便于查看输出。这将打印所需的输出。
-0777
选项使它 slurp 整个文件到 $_
变量中,换行符是 split
。迭代遍历数组索引($#m
是 @m
的最后一个元素的索引)。 $bi
和 $ei
是要打印的 begin/end 索引,在数组的开头和结尾附近不能是 +/- 2。
输出可以通过管道传输到 tail
,但这不能自动进行:如果匹配在最后两行内,则输出行将减少(一两行),因此需要输入以精确切断而闻名。或者在脚本中找到匹配索引,@idx = grep { $m[$_] =~ /exception/} for 0..$#m;
,并在条件中使用它来只打印最后两个。
如果您要使用这样的东西,我会把它做成一个脚本。然后直接将所有行读入数组,提供命令行选项(如grep
中的-C
)等
维护逐行处理会使工作复杂得多。我们需要跟踪匹配项,以便我们可以在阅读后打印以下行。但是这里我们需要 多个 这样的记录——对于下一个匹配项,如果它们出现在要打印的以下行中。
这是一个开始:
$ cat tst.awk
BEGIN { bufSize = 5 }
{ updBuf(NR) }
/exception/ { rangeEndNrs[NR+int(bufSize/2)] }
NR in rangeEndNrs { prtBuf(NR) }
END { prtBuf(NR+1) }
function updBuf(nr) {
buf[((nr-1)%bufSize)+1] = [=10=]
}
function prtBuf(nr, i) {
for (i=1; i<=bufSize; i++) {
print buf[((nr+i-1)%bufSize)+1]
}
print "---"
}
.
$ awk -f tst.awk file
abdgjsd
abdgjsd
exception
exception
exception
---
abdgjsd
exception
exception
exception
abcd
---
exception
exception
exception
abcd
abdgjsd
---
它的工作原理是只保留一个 5 行的输入行缓冲区,并且在任何地方找到 "exception" 设置一个指示器,指示 2 行后缓冲区应该被打印,从而打印 "exception" 行加上前后两行。你只需要按摩它来处理 "exception" 发生在输入文件开头或结尾不到 2 行的情况,但是你想要处理它(看看上面的最后一个输出块是如何环绕的,大概是不受欢迎的缓冲区,因为它 运行 离开输入文件的末尾)。