当前位置: 首页>>技术问答>>正文


grep中这个[t] ricky括号表达式如何工作?

, , ,

问题描述

我最近看到了这个one-liner:

$ ps -ef | grep [f]irefox 

thorsen   16730     1  1 Jun19 ?        00:27:27 /usr/lib/firefox/firefox ...

所以它似乎在数据中返回了”firefox”的进程列表,但是遗漏了grep进程本身,因此看起来大致相当于:

ps -ef |grep -v grep| grep firefox

我无法理解它是如何工作的。我查看了grep和其他地方的手册页,但没有找到解释。

如果我跑:

$ ps -ef | grep firefox  > data
$ grep [f]irefox data

thorsen   15820 28618  0 07:28 pts/1    00:00:00 grep --color=auto firefox
thorsen   16730     1  1 Jun19 ?        00:27:45 /usr/lib/firefox/firefox ....

[t]瑞克似乎停止了工作!

这里有人会知道我发生了什么事。

谢谢。

最佳解决思路

方括号表达式是bash shell(以及其他shell)的一部分,grep的字符类模式匹配。

默认情况下,grep程序了解POSIX基本正则表达式。有了它,您可以定义字符类。例如,ps -ef | grep [ab9]irefox可以找到”airefox”,”birefox”,”9irefox”(如果存在的话),但不能找到”abirefox”。

命令grep [a-zA-Z0-9]irefox甚至可以找到所有以一个字母或数字开头且以”irefox”结尾的进程。

因此ps -ef | grep firefox会在其中搜索带有firefox的行。由于grep进程本身有”firefox”,grep也会找到它。通过添加[],我们只搜索字符类”[f]”(仅包含字母”f”,因此只相当于没有括号的”f”)。现在括号的优点是字符串”firefox”不再出现在grep命令中。因此,grep本身不会出现在grep结果中。

因为通常没有很多人熟悉方括号作为字符类匹配和正则表达式,所以第二个结果可能看起来有点神秘。

如果要修复第二个结果,可以这样使用它们:

ps -ef | grep [f]irefox  > data
grep firefox data

(Reference)

次佳解决思路

原因是字符串

grep firefox

匹配模式firefox,但字符串

grep [f]irefox

与模式[f]irefox(相当于模式firefox)不匹配。

这就是为什么第一个grep匹配它自己的进程命令行,而第二个grep没有。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/2904.html,未经允许,请勿转载。