grep 3最新发生的事件和一些线路发生 [英] grep 3 latest occurences and some lines around the occurence
问题描述
我有一个文件:
exception:anythinggggg ...
exception:anythinggggg ...
abchdhjsdhsd
ygsuhesnkc
例外:anythingggg ...
例外:任何...
..
..
我想grep最近发生的两次异常关键字,以及之前的3行和后面的3行。
我正在使用类似于
grep -C 3异常| tail -12
我在这里使用尾部-12,因为我想每次出现6行,最近出现2次。这种情况很好,当异常发生时彼此远离,但如果说这两个事件都是连续的,就会给我无用的线。
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
例外
例外
例外
abcd
在上面的例子中,它给了我
abdgjsd
abdgjsd
abdgjsd
例外
例外
例外
abcd
然而,我想要的是
abdgjsd
异常
异常----------------->首次发生的产量
例外
abcd
abdgjsd
abdgjsd
例外----------------- >第二次发生的产量
例外
例外
abcd
另一种方式呢?或许我也可以指定出现次数,而不仅仅是grep行和尾部输出。 你得到的输出是因为 grep
在下一场比赛中停止打印上下文( -C
)。我没有看到如何让它表现出来。
下面的脚本(写在命令行上)读取整个文件并形成一行数组。然后它会遍历它并为每个匹配打印周围的两行,或者直到数组的开始/结束。
perl -MList :: Util = min,max -0777 -wnE'
@m = split / \ n /; ($ .. $#m){
if($ m [$ _] =〜/ exception /){
$ bi = max(0,$ _-2);
$ ei = min($ _ + 2,$#m);
表示@m [$ bi .. $ ei];
表示---
}
}
'input.txt
打印 ---
以便于查看输出。这将打印所需的输出。
-0777
选项使它成为 slurp 整个文件放入 $ _
变量中,该变量是换行符拆分
。迭代遍历数组索引( $#m
是 @m
的最后一个元素的索引)。 $ bi
和 $ ei
是要打印的开始/结束索引,在开始时不能为+/- 2和数组的结尾。
输出可以通过管道传输到 tail
,但这不能自动化:if最后两行中的匹配会有(一两个)较少的输出行,因此输入需要知道精确的截止点。或者在脚本中找到匹配的索引,对于0 .. $#m; ,使用 @idx = grep {$ m [$ _] =〜/ exception /},并使用在这种情况下,只打印最后两个。
如果你打算使用这样的东西,我会把它做成一个脚本。然后直接读取所有行到数组中,提供命令行选项(例如 grep
中的 -C
)等。
保持逐行处理会使工作变得更加复杂。我们需要跟踪匹配情况,以便我们在阅读完后可以打印以下内容。但是在这里我们需要多个这样的记录 - 对于下一个匹配(es)以及它们,如果它们在下面的行中进行打印。
I have a file like:
exception: anythinggggg...
exception: anythinggggg...
abchdhjsdhsd
ygsuhesnkc
exception: anythingggg...
exception: anything...
..
..
I want to grep the latest 2 occurrences of exception keyword along with 3 lines before and 3 lines after it.
I am using something like
grep -C 3 exception | tail -12
I am using tail -12 here as I want 6 lines per occurrence and latest 2 occurrences. this works fine when occurrences of exception are far off from each other but gives me useless lines if say both occurrences are consecutive.
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
abdgjsd
exception
exception
exception
abcd
In the above case, it gives me
abdgjsd
abdgjsd
abdgjsd
exception
exception
exception
abcd
however, what I want is
abdgjsd
exception
exception -----------------> OUTPUT FOR FIRST OCCURRENCE
exception
abcd
abdgjsd
abdgjsd
exception-----------------> OUTPUT FOR SECOND OCCURRENCE
exception
exception
abcd
Is there another way to this? Probably something in whch I can also specify the number of occurrences and not just grep lines and tail some output from it.
The output you get is because grep
stops printing context (-C
) at the next match. I don't see how to make it behave otherwise.
The script below (written on the command-line) reads the whole file and forms an array of lines. Then it goes through it and prints surrounding two lines for each match, or up to start/end of array.
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
The ---
are printed for easier reviewing of output. This prints the desired output.
The -0777
option makes it slurp the whole file into the $_
variable, which is split
by newline. The iteration goes over the array index ($#m
is the index of the last element of @m
). The $bi
and $ei
are begin/end index to print, which cannot be +/- 2 near the beginning and end of the array.
The output can be piped to tail
but this can't be automated: if a match is within the last two lines there'll be (one or two) fewer lines of output so input need be known for precise cut-off. Or find indices of matches in the script, @idx = grep { $m[$_] =~ /exception/} for 0..$#m;
, and use that in the condition to only print the last two.
If you are going to use something like this I'd make it a script. Then read all lines into an array directly, provide command-line options (like -C
in grep
), etc.
Maintaining line-by-line processing would make the job far more complicated. We need to keep track of a match so that we can print the following lines once we read them. But here we need multiple such records -- for the next match(es) as well, if they come within the following lines to be printed.
这篇关于grep 3最新发生的事件和一些线路发生的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!