有sed忽略不匹配的行

时间:2009-11-03 06:14:19

标签: sed

如何根据某个表达式使sed过滤匹配行,但忽略不匹配的行,而不是让它们打印?

作为一个真实的例子,我想在一组文件上运行scalac(Scala编译器),并从其-verbose输出中读取创建的.class文件。 scalac -verbose会输出一堆消息,但我们只对[wrote some-class-name.class]形式的消息感兴趣。 我目前正在做的是这个(|&是bash 4.0将stderr传递给下一个程序的方法):

$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/'

这将从我们感兴趣的消息中提取文件名,但也会让所有其他消息保持不变!当然,我们可以这样做:

$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
  sed 's/^\[wrote \(.*\.class\)\]$/\1/'

哪个有效,但看起来非常像绕过真正的问题,这就是如何指示sed忽略输入中不匹配的行。那我们该怎么做呢?

5 个答案:

答案 0 :(得分:216)

如果您不想打印不匹配的行,可以使用

的组合
  • -n选项告诉sed不打印
  • p标志告诉sed打印匹配的内容

这给出了:

sed -n 's/.../.../p'

答案 1 :(得分:78)

普通sed的另一种方式:

sed -e 's/.../.../;t;d'

s///是一个替换,t没有任何标签有条件地跳过以下所有命令,d删除行。

不需要perl或grep。

(根据Nicholas Riley的建议编辑)

答案 2 :(得分:1)

使用Perl:

... |& perl -ne 'print "$1\n" if /^\[wrote (.*\.class)\]$/'

答案 3 :(得分:0)

sed -n '/.../!p'

无需替换。

答案 4 :(得分:0)

Rapsey提出了有关多个替换表达式的相关观点。

  • 首先,quoting an Unix SE answer,您可以“为大多数sed命令添加地址前缀,以限制它们所应用的行”。
  • 第二,您可以将命令括在大括号 {} 中(用分号 ; 或换行分隔)
  • 第三,在最后一个替换项上添加打印标记 p

语法:

sed -n -e '/^given_regexp/ {s/regexp1/replacement1/flags1;[...];s/regexp1/replacement1/flagsnp}'

示例(有关更多详细信息,请参见Here document

  • 代码:

    sed -n -e '/^ha/ {s/h/k/gp;s/a/e/g}' <<SAMPLE
    haha
    hihi
    SAMPLE
    
  • 结果:

    kaka