Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix grep上下文反向搜索_Unix_Shell_Sed_Grep - Fatal编程技术网

Unix grep上下文反向搜索

Unix grep上下文反向搜索,unix,shell,sed,grep,Unix,Shell,Sed,Grep,我想过滤掉文件中匹配行前后的几行。 这将删除我不想要的行: $ grep -v "line that i don't want" $ grep -C 2 "line that i don't want" # does not remove 2 lines before and after the line I don't want: $ grep -v -C 2 "line that i don't want" 这将在我不想要的行之前和之后打印两行: $ grep -v "line

我想过滤掉文件中匹配行前后的几行。

这将删除我不想要的行:

$ grep -v "line that i don't want"
$ grep -C 2 "line that i don't want"
# does not remove 2 lines before and after the line I don't want:
$ grep -v -C 2 "line that i don't want"   
这将在我不想要的行之前和之后打印两行:

$ grep -v "line that i don't want"
$ grep -C 2 "line that i don't want"
# does not remove 2 lines before and after the line I don't want:
$ grep -v -C 2 "line that i don't want"   
但当我将它们组合在一起时,它不会过滤掉我不想要的行之前和之后的两行:

$ grep -v "line that i don't want"
$ grep -C 2 "line that i don't want"
# does not remove 2 lines before and after the line I don't want:
$ grep -v -C 2 "line that i don't want"   
我如何过滤掉不想要的行,以及前后的行?我猜sed
sed
更适合这个

编辑:我知道这可以在awk/Perl/Python/Ruby/等的几行代码中完成,但我想知道是否有一行简洁的命令可以从命令行运行。

awk'BEGIN{n=2}{a[++I]=0}
awk 'BEGIN{n=2}{a[++i]=$0}
/dont/{
  for(j=1;j<=i-(n+1);j++)print a[j];
  for(o=1;o<=n;o++)getline;
  delete a}
END{for(i in a)print a[i]} ' file
/不要/{ 对于(j=1;j试一下:

sed 'h;:b;$b;N;N;/PATTERN/{N;d};$b;P;D' inputfile
您可以更改模式之前的
N
命令数,以影响要删除的行数

您可以通过编程方式构建一个包含
N
命令数的字符串:

C=2 # corresponds to grep -C
N=N
for ((i = 0; i < C - 1; i++)); do N=$N";N"; done
sed "h;:b;\$b;$N;/PATTERN/{N;d};\$b;P;D" inputfile
C=2#对应于grep-C
N=N
对于((i=0;i
如果行都是唯一的,您可以将要删除的行grep到文件中,然后使用该文件从原始行中删除行,例如

grep -C 2 "line I don't want" < A.txt > B.txt
grep -f B.txt A.txt
grep-c2“我不想要的行”B.txt
grep-f B.txt A.txt

我认为@fxm27有一个非常好的答案

我想补充一点,如果您事先知道后续行的模式,您可以通过使用egrep以另一种方式解决这个问题

command | egrep -v "words|from|lines|you|dont|want"

这将产生一个“inclusive OR”,这意味着匹配其中任何一个的行将被排除。

事实上,我用两个连续的grep解决了这个问题。对我来说,这似乎更简单

grep -C "match" yourfile | grep -v -f - yourfile

2019年解决方案

这是一个简单的解决方案,可在其他地方找到:

grep——反向匹配“测试”
选择所有不匹配的“测试*”。超级有用且易于记忆

(编辑)


这不能完全回答原始问题并返回不匹配的整组行。

不,你的意思是
grep
就是不能这样做?!有什么原因吗?这是违反直觉的me@naxa:当
-C
-v
一起使用时,
-C
包括排除的行,而不是排除添加所有行。请尝试以下操作:
printf'%s\n'{1..36}| grep--color-c2-v'^2.
您将看到20、21、28和29被包括在内,而不是18、19、30和31被排除在外。顺便说一句,
-C
选项不是POSIX指定的。啊,我明白了。非常感谢您的关注和现在的彩色示例!我已经尝试了-A和-B,但它们的工作原理类似于-C。它们似乎也一样现在我知道我错过了什么,我很难理解你的一行sed是如何一个命令一个命令地执行的,即使在手册页的帮助下。我可能会稍后再复习,但如果不是太麻烦,你介意把它分解一下吗?我想这会有利于回答的质量。我知道你可能是一个我已经知道这一点了,因为你的XP比我多得多,但是你可能想添加一点解释,而不仅仅是代码段,解决OP要求一个grep解决方案的事实,同时提供你的非常有效和非常有用的AWK解决方案。谢谢!@DermotCanniffe,lol公认的答案甚至更复杂ng sed。非常正确。虽然我非常喜欢sed,但我认为awk程序更容易解释。:)此解决方案不会删除next和after模式匹配行。此解决方案并不总是有效;有关详细信息,请参阅。是否可以将此行与侧文件一起删除:
grep-C1不需要的a.txt | grep-vFf-a.txt
…这使用从stdin读取“文件”的
-f-
。此外,对于固定字符串,我建议使用
-f
。最后,OP是省略的ng
-v