9.11 在其他命令的输出中搜索特定内容
$ ls -1 | grep 1960
grep
命令单独使用时就很强大,但把它作为其他程序输出的过滤器来使用,才真正显示出它的光彩。例如,假设你把所有John Coltrane的MP3按专辑(是的,总共66个,Coltrane相当优秀)组织到单独的子文件夹中,每个文件夹的名称以年份作为开始。部分列表如下所示(ls
命令使用了-1
选项,所以每行只显示一个结果):
$ ls -1
1956_Coltrane_For_Lovers
1957_Blue_Train
1957_Coltrane_[Prestige]
1957_Lush_Life
1957_Thelonious_Monk_With_John_Coltrane
现在,如果你只想看看自己所有的Coltrane在1960年发行的专辑,该怎么办呢?将ls -1
的结果通过管道输出到grep
,几秒钟内就能得到答案。如下所示:
$ ls -1 | grep 1960
1960_Coltrane_Plays_The_Blues
1960_Coltrane's_Sound
1960_Giant_Steps
1960_My_Favorite_Things
在经过思考以后,你会发现按这种方式来使用grep
,其用法至少也有几百种。这里再演示另一种功能强大的用法。ps
命令可以列出运行中的进程,而-f
选项能够让ps
提供完整的列表,其中包括每个进程的很多信息;而-U
选项,后面跟上用户名称,可以限制只输出那个用户拥有的进程。通常,ps -fU scott
会产生一个很长的列表,如果要搜索特定进程的信息,这种输出就太长了。不过,在grep
的帮助下,就能够轻松地限制输出内容。
说明 为了节省篇幅,这里删除了一些使用
ps
命令通常可以看到的信息。
$ ps -fU scott | grep firefox
scott 17623 /bin/sh /opt/firefox/firefox
scott 17634 /opt/firefox/firefox-bin
scott 1601 grep firefox
ps
命令会列出用户scott
拥有的全部进程(实际上有64个),但将输出通过管道发给grep
命令之后,只列出其中包含firefox的那些进程。遗憾的是,输出的最后一行是错误的。你关心的只是实际的Firefox程序,而不是用grep
搜索firefox
这样的信息。要在grep
结果中隐藏firefox
的搜索信息,试试以下命令:
$ ps -fU scott | grep [f]irefox
scott 17623 /bin/sh /opt/firefox/firefox
scott 17634 /opt/firefox/firefox-bin
现在,grep
的搜索内容是通过正则表达式的一个范围(从f到f)来定义的,用它可以找到ps
输出中包含firefox
的那些行(表示相应的进程正在运行Firefox)。不过,它不匹配grep
行,因为这行的内容实际上是[f]irefox
,所以不匹配。这里grep
命令也不能匹配原始的命令字符串ps -ef | grep [f]irefox
,因为它包含了[
和]
字符,而用于搜索[f]irefox
的grep
在运行时搜索的是精确的“firefox”这个词。这点难理解了吧,不过,亲自试一试,多仔细想想,就能领悟其意义了。