如果我的 grep 不支持 -B 选项,我如何找到匹配之前的行?

问题描述 投票:0回答:3

我需要在 grep 输出之前查看 5 行。
我使用了命令,

grep -B 5 pattern filename

但是抛出了错误

/usr/bin/grep: illegal option --B

如何处理这种情况并查看grep语句之前的5行?

unix grep
3个回答
0
投票

您考虑过使用

awk
吗?

如果这是一个可行的选项,请选中这一行:

$ awk '/PATTERN/{for(i=1;i<=x;)print a[i++];print}{for(i=1;i<x;i++)a[i]=a[i+1];a[x]=$0;}' x=5 file

上面的命令将返回匹配模式之前的五行和匹配的模式(即总共 6 行,而

grep -B 5
总共返回五行,包括匹配的一行)。

x
指定行数

我希望这有帮助。


0
投票

Simply_Me 的答案是正确的,但会复制每个不匹配项上的所有先前行。 (挑剔的技术细节:即使 gawk 的实现避免了复制字符串本身,它仍然必须重新散列索引)。所以,仍然坚持使用 awk:

#!/usr/bin/awk -f

BEGIN { cl=1; }

/foo5/ {
    for (i=cl; i<cl+N; i++)
    print pLines[i % N];
    cl=1;
}

{  pLines[cl % N] = $0; cl = cl + 1; }

cl 代表当前行。如果我们有匹配项,我们将打印之前存储在 pLines 数组中的 N 行。您可能希望打印图案本身,但我没有。无论看到模式如何,我们都会使用 % 运算符将刚刚处理的行存储在 pLines 中,因此我们不必移动数组。

为了

zoo0
blah1
foo2
bar3
hehe4
lisp5
foo5
blah6
foo7
bar8
hehe9
foo5

此打印

blah1
foo2
bar3
hehe4
lisp5
foo5
blah6
foo7
bar8
hehe9

这是不包括模式的前 5 行。

它也可以合理地工作

hehe4
lisp5
foo5
blah6
foo7
bar8
hehe9
foo5

在 foo5 的第一个匹配之前没有前 5 行。在这种情况下,它打印空行。您可能需要根据您的需求进行定制。


0
投票

哎哟!

这是 Perl 中的解决方案。 因为这些行是“比赛之前”的,所以您必须使用缓冲区。 我包含了一个 $bufferSize 命令行参数。 名为 @buffer 的数组将始终包含最后 $bufferSize 行。 当找到匹配项时,打印末尾包含匹配行的缓冲区。 这是代码。 我在 Larry Wall 编写的《Programming Perl》文本文件上运行了这个。 #!/usr/bin/perl -w =begin #usage perl thisFile.pl bufferSize inputFile #print n lines before match. Because it is BEFORE the match, you will need to use a buffer. I have limited the buffer to just the given bufferSize, but you could store the entire file in a buffer if need be. =end =cut my $bufferSize = shift; #grab buffer size from command line arguments my @buffer; while(<>){ push(@buffer, "$_"); #store current line in buffer to be accessed when a match is found if($#buffer > $bufferSize){ shift(@buffer); } #if the buffer is bigger than $bufferSize, remove a line from the beginning of the array with shift, pop removes from the end of the array if(/diamond/i){ #match found, print buffer print "\n\n***Match Found: Line $.***\n"; my $i=1; for(@buffer){print "$i\t: $_"; $i++;} } }

输出看起来像这样

$ perl print.n.lines.before.match.pl 15 programming.perl.txt ***Match Found: Line 25975*** 1 : stalled on the target system. (It might need some shared libraries, though, if you 2 : didn’t link everything statically.) However, this program isn’t really any different 3 : than the regular Perl interpreter that runs your script. It’s just precompiled into 4 : a standalone executable image. 5 : The B::CC module, however, tries to do more than that. The beginning of the C 6 : source file it generates looks pretty much like what B::C produced5 but, eventu- 7 : ally, any similarity ends. In the B::C code, you have a big opcode table in C that’s 8 : manipulated just as the interpreter would do on its own, whereas the C code 9 : generated by B::CC is laid out in the order corresponding to the runtime flow of 10 : your program. It even has a C function corresponding to each function in your 11 : program. Some amount of optimization based on variable types is done; a few 12 : benchmarks can run twice as fast as in the standard interpreter. This is the most 13 : ambitious of the current code generators, the one that holds the greatest promise 14 : for the future. By no coincidence, it is also the least stable of the three. 15 : Computer science students looking for graduate thesis projects need look no fur- 16 : ther. There are plenty of diamonds in the rough waiting to be polished off here.

这里有一个解决方案,可以在此处类似的问题中找到匹配后的 n 行。

匹配模式后打印特定行数

几乎完全相同,但不需要缓冲区,因为这些行位于匹配之后。

#!/usr/bin/perl -w #usage perl thisFile.pl bufferSize inputFile #print n lines after match $n = shift; while(<>){ if( /diamond/i ){ print "\n\n***Match found: Line $.***\n$_"; #print header and matching line #print next 81 lines for( 1 .. $n ){ print "$_:\t" . <>; } } }

输出看起来像这样

$ perl print.n.lines.after.match.pl 15 programming.perl.txt ***Match found: Line 25975*** 0: ther. There are plenty of diamonds in the rough waiting to be polished off here. 1: 2: 3: Code Development Tools 4: The O module has many interesting Modi Operandi beyond feeding the exasper- 5: atingly experimental code generators. By providing relatively painless access to 6: the Perl compiler’s output, this module makes it easy to build other tools that 7: need to know everything about a Perl program. 8: The B::Lint module is named after lint(1), the C program verifier. It inspects 9: programs for questionable constructs that often trip up beginners but don’t nor- 10: mally trigger warnings. Call the module directly: 11: % perl –MO=Lint,all myprog 12: 13: 14: 15:

祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.