grep -A 2 -B 3
在 grep 字符串之后打印 2 行,并在之前打印 3 行。
grep -C 3
打印前 3 行和后 3 行
不幸的是,grep
我正在使用的不支持这些选项。是否有任何替代命令或脚本可用于模拟此操作?使用sed
/// shell脚本awk
?perl
答案1
一种相当丑陋的方法是
grep -v pattern file >file.tmp; diff -c file.tmp file
或者用 替换-c
上下文-C NUM
行NUM
。不过,它会产生额外的输出。(如果你diff
支持-u
/ -U NUM
,它会更干净。)
如果你diff
没有-c
// -C
,-u
仍然有办法做到这一点,但它们非常丑陋。另一方面,一个diff
不支持 Perl的系统-c
可能也没有 Perl。
答案2
答案3
这个简单的 perl 脚本grep -A
在某种程度上模拟
#!/usr/bin/perl
$pattern=shift; #patthern to search
$lines=shift; # number of lines to print
$n = 0;
while (<>) {
$n = $lines if /$pattern/; # reset counting
if ($n) { print; $n-- } # print if within
$n = 0 if eof; # don't leak across file boundaries
}
请注意,您可以添加使用语句,以使脚本可读且可用;)
USAGE: $./grep-A.pl <pattern> <numLines> <filename>
答案4
事实证明,模拟 -B 相当棘手,因为当匹配行直接相互跟随时会出现问题。这几乎不允许使用任何类型的单通道文件扫描。
我在尝试以下近似值时意识到了这一点:
perl -pe 'if(/search_term/) {print foreach @A; print ">"; $B=4}; shift @A if push(@A, $_)>7; $_ = "" unless ($B-- > 0);' target_file
这将大致正确地与 grep -A7 -B3 一样,并带有第一段中描述的警告。
此问题的另一种(也是单文件)解决方案是使用 perl 向 sed 提供命令字符串:
sed -n `perl -pe '$_=(/search_term/?sprintf("%d,%dp;", $.-3,$.+4):"")' file` file