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

Tho*_*sen 41 command-line bash grep

我最近看到了这个单行:

$ ps -ef | grep [f]irefox 

thorsen   16730     1  1 Jun19 ?        00:27:27 /usr/lib/firefox/firefox ...
Run Code Online (Sandbox Code Playgroud)

因此,它似乎返回数据中带有“firefox”的进程列表,但忽略了 grep 进程本身,因此似乎大致相当于:

ps -ef |grep -v grep| grep firefox
Run Code Online (Sandbox Code Playgroud)

我无法理解它是如何工作的。我查看了 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 ....
Run Code Online (Sandbox Code Playgroud)

[t]rick 似乎停止工作了!

这里有人会知道发生了什么我敢肯定。

谢谢。

jok*_*ino 62

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

grep程序默认理解 POSIX 基本正则表达式。有了它,您可以定义字符类。例如,ps -ef | grep [ab9]irefox会找到“ a irefox”、“ b irefox”、“ 9 irefox”(如果存在),但不会找到“ ab irefox”。

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

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

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

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

ps -ef | grep [f]irefox  > data
grep firefox data
Run Code Online (Sandbox Code Playgroud)

(参考)

  • 实际上在这种情况下,我认为它不会在 grep 之前被 shell 解释。我认为 `[f]` 是字符类的正则表达式模式匹配括号。正如在“[a-z0-9]irefox”中一样,grep 也会匹配“airefox”和“0irefox”。您可以很容易地看到它不是内置的 bash,因为 `echo $([f])` 返回一个错误。 (6认同)
  • `[f]irefox` 用于此目的的具体原因是它*不*被 shell 扩展。当 shell 将 `[f]irefox` 扩展为 `firefox` 时,这会导致 `grep` 看到 `firefox`,然后 `firefox` 是 `grep` 的命令字符串的一部分,就好像 `grep firefox` 是跑。但是**记住shell模式匹配是很好的**,尤其是在编写脚本时,因为[如果当前目录中有一个名为`firefox`的文件](http://paste.ubuntu.com/10878943/), **然后shell *确实* 将`[f]irefox` 扩展为`firefox`** 并且此方法失败,即显示了来自`ps` 的`grep` 行。 (5认同)

Dan*_*ich 10

原因是字符串

grep firefox
Run Code Online (Sandbox Code Playgroud)

匹配模式firefox,但字符串

grep [f]irefox
Run Code Online (Sandbox Code Playgroud)

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

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