【问题标题】:Combine -v option for grep with -A option将 grep 的 -v 选项与 -A 选项结合使用
【发布时间】:2016-08-11 21:57:22
【问题描述】:

我想问一下 -v 和 -A 可以以某种方式结合吗?

我有示例文件:

abc
1
2
3
ACB
def
abc
1
2
3
ABC
xyz

使用 -A 我可以看到我想要“剪切”的部分:

$ grep abc -A 4 grep_v_test.txt
abc
1
2
3
ACB
--
abc
1
2
3
ABC

它有一些选项可以指定只看的东西

def
xyz

?

我找到了这个答案 - Combining -v flag and -A flag in grep 但它对我不起作用,我试过了

$ sed -e "/abc/{2;2;d}" grep_v_test.txt
sed: -e expression #1, char 8: unknown command: `;'

还有

$ sed "/abc/2d" grep_v_test.txt
sed: -e expression #1, char 6: unknown command: `2'

$ sed "/abc/+2d" grep_v_test.txt
sed: -e expression #1, char 6: unknown command: `+'

Sed 版本是:

$ sed --version
GNU sed version 4.2.1

编辑1: 根据评论,我对这两种解决方案都进行了一些试验,但它并没有像我想要的那样工作

对于grep -v -A 1 abc,我希望删除行 abc 和 1,但将打印其余部分 awk 'c&&!--c; /abc/ {c=2}' grep_v_test.txt 仅打印包含 2 的行,这不是我想要的。

与 sed 非常相似

$ sed -n '/abc/{n;n;p}' grep_v_test.txt
2
2

edit2: 看来,我无法正确描述它,让我再试一次。

grep -A N abc file 所做的是在 abc 之后打印 N 行。我想删除grep -A 将显示的内容,所以在一个文件中

abc
1
2
3
ACB
def
DEF
abc
1
2
3
ABC
xyz
XYZ

我将删除部分 abc 到 ABC,然后打印其余部分:

abc
1
2
3
ACB
def
DEF
abc
1
2
3
ABC
xyz
XYZ

所以将保留 4 行... awk 解决方案仅打印 def 和 xyz 并跳过 DEF 和 XYZ...

【问题讨论】:

  • 只需使用awk ----> awk 'c&&!--c; /abc/ {c=5}' file
  • 感谢您的回答,它工作正常,但我仍然想知道使用 sed 的答案(与 awk 相比,我是那个更大的朋友)。
  • 然后使用Printing next line with sed 得到sed -n "/abc/{n;n;n;n;n;p}" file
  • 现在我对前面的例子有了更好的理解,但这并不是真正的 grep -v,它没有打印不匹配的行......
  • 我提到的两个单行代码都是这样做的:匹配内容为“abc”的行,然后打印其后的第 5 行。

标签: grep


【解决方案1】:

要跳过从初始匹配行开始的 5 行上下文是:

$ awk '/abc/{c=5} c&&c--{next} 1' file
def
xyz

其他相关脚本见Extract Nth line after matching pattern

wrt 下面的 cmets,这是这个答案和 @fedorqui's answer 之间的区别:

$ cat file
now is the Winter
of our discontent
abc
1
2
bar

$ awk '/abc/{c=3} c&&c--{next} 1' file
now is the Winter
of our discontent
bar

$ awk '/abc/ {c=0} c++>2' file
bar

看看@fedorqui 的脚本如何无条件跳过文件的前两行?

【讨论】:

  • 我不清楚有什么区别。当我更改文件“abc”->“x abc”的内容并使用相同的命令时,它起作用了,所以看起来,你的陈述“这只是你想要的,因为 abc 出现在文件的开头。”是不正确的。我不清楚(也在链接页面上)这个 1{next} 用于...
  • 当您将abc 更改为x abc 并没有改变abc 出现在文件开头的事实 - 您没有从第一行删除abc,您刚刚在同一行添加了其他内容。尝试在您当前的第一行之前放置一个全新的行,例如foo1 是一个真正的条件,它会导致打印当前记录的默认操作发生,这是一个非常常见的 awk 习惯用法。 next 告诉 awk 停止处理当前记录。如果您打算进行任何文本操作,我推荐 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书。
  • @Betlista 我编辑了我的答案以包含一个示例,向您展示这两个脚本之间的区别。
【解决方案2】:

如果我理解正确,您想打印给定匹配后 4 行出现的所有行。

为此,您可以调整Extract Nth line after matching pattern 中的解决方案并说:

$ awk '/abc/ {c=0} c++>4' file
def
DEF
xyz
XYZ

【讨论】:

  • 谢谢,这似乎正是我想要的,但正如我所说,我对 awk 不是那么大的朋友......当我现在看到它时似乎很简单......
  • @Betlista 您可以尝试在sed 中编写此代码,但它可能会变得很疯狂,因为它是一个逐行处理的工具。我更喜欢awk,因为在考虑所有上下文的情况下处理文件是件好事。它也很整洁:)
  • 我已经喜欢你的解决方案了。我想要一些像 grep 一样简单的检查 / wothout -v 并从 c++ > 4 更改为 c++ <= 4 是如此简单;-)
  • 这只是你想要的,因为abc 出现在文件的开头。如果没有,那么该命令无论如何都会跳过前 5 行。
  • @Betlista 所以是的,Ed 的解决方案涵盖了所有情况。
猜你喜欢
  • 2018-06-01
  • 2013-12-22
  • 2018-10-17
  • 2015-04-16
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 2022-11-26
  • 1970-01-01
相关资源
最近更新 更多