让 sed 忽略不匹配的行 [英] Have sed ignore non-matching lines
问题描述
如何让 sed
根据某些表达式过滤匹配的行,但忽略不匹配的行,而不是让它们打印?
How can I make sed
filter matching lines according to some expression, but ignore non-matching lines, instead of letting them print?
作为一个真实的例子,我想在一组文件上运行 scalac
(Scala 编译器),并从它的 -verbose
输出中读取 .类
文件创建.scalac -verbose
输出一堆消息,但我们只对 [wrote some-class-name.class]
形式的那些感兴趣.我目前正在做的是这个(|&
是 bash 4.0 将 stderr 通过管道传输到下一个程序的方式):
As a real example, I want to run scalac
(the Scala compiler) on a set of files, and read from its -verbose
output the .class
files created. scalac -verbose
outputs a bunch of messages, but we're only interested in those of the form [wrote some-class-name.class]
.
What I'm currently doing is this (|&
is bash 4.0's way to pipe stderr to the next program):
$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/'
这将从我们感兴趣的消息中提取文件名,但也会让所有其他消息不变地通过!当然,我们可以这样做:
This will extract the file names from the messages we're interested in, but will also let all other messages pass through unchanged! Of course we could do instead this:
$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
sed 's/^\[wrote \(.*\.class\)\]$/\1/'
可行,但看起来很像解决真正的问题,即如何指示 sed
忽略输入中的不匹配行.那么我们该怎么做呢?
which works but looks very much like going around the real problem, which is how to instruct sed
to ignore non-matching lines from the input. So how do we do that?
推荐答案
另一种简单的 sed 方法:
Another way with plain sed:
sed -e 's/.../.../;t;d'
s///
是一个替代,t
不带任何标签有条件地跳过后面的所有命令,d
删除一行.
s///
is a substituion, t
without any label conditionally skips all following commands, d
deletes line.
不需要 perl 或 grep.
No need for perl or grep.
(根据 Nicholas Riley 的建议编辑)
(edited after Nicholas Riley's suggestion)
这篇关于让 sed 忽略不匹配的行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!