如何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/'
Run Code Online (Sandbox Code Playgroud)
这将从我们感兴趣的消息中提取文件名,但也会让所有其他消息保持不变!当然我们可以这样做:
$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
sed 's/^\[wrote \(.*\.class\)\]$/\1/'
Run Code Online (Sandbox Code Playgroud)
哪个有效,但看起来非常像绕过真正的问题,这是如何指示sed
从输入中忽略不匹配的行.那我们该怎么做呢?
mou*_*iel 226
如果您不想打印不匹配的行,可以使用组合
-n
告诉sed不要打印的选项p
告诉sed打印匹配的标志这给出了:
sed -n 's/.../.../p'
Run Code Online (Sandbox Code Playgroud)
lio*_*ori 80
普通sed的另一种方式:
sed -e 's/.../.../;t;d'
Run Code Online (Sandbox Code Playgroud)
s///
是一个替代品,t
没有任何标签有条件地跳过所有以下命令,d
删除行.
不需要perl或grep.
(根据Nicholas Riley的建议编辑)