【问题标题】:Combining -v flag and -A flag in grep在 grep 中结合 -v 标志和 -A 标志
【发布时间】:2015-10-23 01:58:16
【问题描述】:

我需要在文件中搜索字符串,删除包含该字符串的任何行,并删除包含该字符串的任何行后面的两行。我希望我能用这样的东西来完成这个......

$ grep -v -A 2 two temp.txt
one
five
$

...但不幸的是,这不起作用。有没有一个简单的我可以用 grep 或其他 shell 命令来做到这一点?

【问题讨论】:

    标签: unix sed grep


    【解决方案1】:

    以下内容适用于 GNU sed 和 OS X。

    $ sed '/two/{N;N;d;}' temp.txt
    one
    five
    
    • 查找行匹配two
    • 再读两行
    • 删除它们

    【讨论】:

    • 您的答案和@JohnKugelman 的答案都很简洁,它们都适用于 GNU/Linux,但都不适用于 OS X(对于我来说,对于这个特定的任务来说这不是什么大问题)。为了提供语法的简要说明,接受的答案将交给您。谢谢。
    • 在 d 和之后添加分号。强制使用大括号,它也应该在 MacOS X 上工作。
    【解决方案2】:

    您可以使用awk 执行此操作,具体如下:

    pax> echo 'one
    two
    three
    four
    five' | awk '/two/ {skip=3} skip>0 {skip--;next} {print}'
    
    one
    five
    

    当它在一行上找到two 字符串时,它基本上会启动一个行计数器来丢弃 (3)。然后它会丢弃这些行,直到跳过计数器达到零。打印任何未标记为跳过的行。

    【讨论】:

    • 这样的好处是可以正确处理one two three two three four fiveone five
    【解决方案3】:

    使用 GNU sed:

    sed '/two/,+2d' temp.txt
    

    这使用双地址语法 (addr1,addr2) 来匹配包含单词 2 (/two/) 加上后面的两行 (+2) 的行。 d 命令删除这些行。

    【讨论】:

    • 我唯一能想到的可能是他们使用的是较旧的非 GNU sed,没有 +number 选项。但既然它有效(而且我不喜欢开车投反对票的人),这是一个推翻它的投票。
    【解决方案4】:

    这是使用 Perl 的一种方法:

    $ perl -ne'if (/two/){$x=<>;$x=<>;}else{print}' temp.txt 
    one
    five
    

    -n 是对输入的隐式循环。如果匹配/two/,则阅读接下来的两行,否则打印你所在的行。

    然而,问题是,如果第三行或第四行匹配 /two/,那么您仍然会得到相同的输出。 @paxdiablo 的解决方案更完整。但我的 Q&D 更多。

    【讨论】:

      猜你喜欢
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 2020-03-31
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      相关资源
      最近更新 更多