grep 命令和 [ ]

grep 命令和 [ ]

我正在学习 bash 代码,今天正在学习命令grep

如果我跑

$ ps -fU user | grep thunderbird

终端显示:

user  17410     1  0 10:09 ?        00:00:20 /usr/lib/thunderbird/thunderbird
user  18990 15896  0 12:25 pts/1    00:00:00 grep --color=auto thunderbird

但如果我运行:

$ ps -fU user | grep [t]hunderbird

终端显示:

user  17410     1  0 10:09 ?        00:00:20 /usr/lib/thunderbird/thunderbird

为什么?我读了指南,但我不明白。

答案1

这里有两个问题。首先,当你运行 时ps | grep ...grep进程也会显示在 的输出中ps。默认ps输出不仅包括进程的名称,还包括启动进程时使用的参数。这意味着如果你运行grep foo,并且有一个名为 的正在运行的进程foo,则会有两个ps匹配的结果foofoo进程和grep本身,因为它正在搜索foo。这就是你在运行 时得到两行的原因ps -f | grep thunderbird

现在,[ ]是一个正则表达式构造,它定义了一个字符列表,即一个字符类。例如,[abc]将匹配abc。当您运行 时ps -f | grep [t]hunderbird,该类仅包含一个字符,因此相当于thunderbird不带括号的 。但是,这次grep启动该进程[t]hunderbird时使用的是 而不是 作为参数thunderbird。因此, 输出中的行将ps包含[t]hunderbird。它将如下所示:

terdon   23101 10991  0 16:53 pts/3    00:00:00 grep --color [t]hunderbird

这意味着运行时它不匹配,ps -f | grep thunderbird因为它包含[t]hunderbird和不包含thunderbird

grep这是在运行 时避免匹配进程本身的常用技巧ps | grep。另一种选择是运行ps -f | grep foo | grep -v grep以排除grep。然而,最好的方法是使用专门为此设计的程序pgrep

$ pgrep -l thunderbird
11330 thunderbird

答案2

在第一种情况下,您要查找带有单词 thunderbird 的任何进程。有两个 thunderbird 和 grep 命令本身。

在第二个中,您还要查找t后跟的字符hunderbird,因为 [t] 表示匹配方括号中列出的任何字符,其中只有一个,即字母 t,但这次您的两个过程是

user  17410     1  0 10:09 ?        00:00:20 /usr/lib/thunderbird/thunderbird
user  18990 15896  0 12:25 pts/1    00:00:00 grep --color=auto [t]hunderbird

第二个进程不匹配,因为 rexep [t]hunderbird 与文字字符串 [t]hunderbird因为] 阻止了匹配。

答案3

首先,是否grep --color=auto thunderbird会出现在进程表中,从而出现在的输出中ps取决于时间,即您的系统有多忙,以及需要多长时间才能ps在其输出中显示已并发启动的内容(通过解析进程表),grep在本例中。虽然这种情况极不可能发生,但我们可以假设它将grep出现在的输出中ps

现在,[]是一个 grep 语法,这意味着(如果没有其他标记)匹配 内的任何字符[]。因此,当您使用 时grep '[t]hunderbird'grep会将 视为[t]仅匹配t,因此它不会出现在输出中。

在使用时grep thunderbird,如果它在进程表中存在,我们会grep在输出中找到该进程,因为我们grep对同一件事进行 -ping ,即grep thunderbird

还请注意,这grep是一个别名,会grep --color=auto导致它也出现在输出中。

答案4

中的 []grep用于字符匹配。如果我们取 grep [tb]all my_file.txt

它相当于

grep tall my_file.txt
grep ball my_file.txt

它将grep通过取 t+all 来执行,然后它将grep通过取 b+all 来执行。

例如:如果我们想在文件中查找单词 ABC 或 BBC,我们可以使用以下 grep 命令:

grep [AB]BC file_name 

这里 [] 将grep通过采用 A 来扩展单词,然后它将通过使用 B 来扩展单词,从而创建 ABC 和 BBC。

相关内容