使用 grep 的两种命令的区别

Rap*_*ael 5 command-line grep

所以,这里我们有两个命令:

cat /var/log/dpkg.log | grep " \install\ "
cat /var/log/dpkg.log | grep install
Run Code Online (Sandbox Code Playgroud)

为什么这些命令的输出不同?能否请您稍微解释一下第一个命令。先感谢您。

Byt*_*der 8

两个命令的第一部分 ( cat FILENAME) 始终相同,只是将指定文件的内容打印到 STDOUT 流。我不会再解释了。

我们的兴趣点是grep零件。

的语法grep

grep [OPTIONS] PATTERN [FILE...]
Run Code Online (Sandbox Code Playgroud)

您可以传递grep一些选项来调整其行为(例如设置使用的 RegEx 风格或控制输出格式),但在您的情况下不使用这些选项。

下一个参数必须是要匹配的模式,其中需要正则表达式(“RegEx”)或固定字符串(如果grep使用-F选项调用)。在您的示例中,这是installor"\ install\ "部分。我将在下一段中解释它。

之后,您指定要匹配的数据源。这可以是文件名,也可以什么都没有。在第二种情况下,grep将从 STDIN 流(标准输入:通常是您用键盘键入的内容)中读取,您可以在其中通过管道 ( |) 从前一个命令中获取输出。

如何正确传递“PATTERN”参数?

模式参数必须是单个参数。这意味着,您不能在此处仅传递几个单词或任何包含空格或 shell 特殊字符的内容,因为空格在 Bash 中被视为参数分隔符,并且可能在所有其他 shell 中也是如此,并且 shell 特殊字符(例如);会破坏命令。

但是您有两种选择可以在模式中包含空格以进行匹配:

  • 将整个字符串放在单 ( '...') 或双 ( "...") 引号中进行匹配。这样,shell 将整个用引号括起来的字符串解析为一个参数并将其传递给grep.

  • 使用反斜杠 ( \)转义模式中的每个空格。这意味着,您在每个不想被 shell 视为参数分隔符的空格之前写一个反斜杠。但请注意,如果您想在模式中使用实际的反斜杠,您也必须通过在它之前编写另一个反斜杠来将其转义。

如果我们现在分析您的两个grep命令示例的差异,我们会看到它们匹配的差异:

cat /var/log/dpkg.log | grep "\ install\ "
Run Code Online (Sandbox Code Playgroud)

这与模式匹配install。(注意前导和尾随空格!)

在这里,我们看到了两种方法:整个模式周围的双引号和反斜杠 - 转义其中的空格。老实说这是多余的,一个就足够了。虽然在这种情况下它不会受到伤害,但您不应该这样做并决定一种方法。通常我会建议使用引号,因为它更容易阅读。

cat /var/log/dpkg.log | grep install
Run Code Online (Sandbox Code Playgroud)

这与模式匹配install。(周围没有空间。)

这里的模式只包含单词install,没有别的。没空间了。

您的命令之间的区别:

正如我所说,你的第一个例子只匹配install被空格包围的单词。如果例如在它之前或之后直接有句号或任何其他字符,则它将不匹配。它也不会直接匹配行首或行尾的单词。

第二个示例不关心单词前后的任何空格install。它还匹配行的开头和结尾,以及它是否被任何标点符号包围。如果在任何地方都有包含此字母序列的单词,它甚至会匹配,例如“卸载”、“重新安装”或“安装”!

正确/有用的反斜杠转义示例:

就像在您提供的示例中,反斜杠是多余的,这里是没有引号的相同示例,但仅使用反斜杠转义:

cat /var/log/dpkg.log | grep \ install\ 
Run Code Online (Sandbox Code Playgroud)

或者,如果您想在/home/you/path with spaces/textfile不使用引号的情况下匹配文件中的字符串“I like Ubuntu” ,您可以这样做:

grep I\ like\ Ubuntu /home/you/path\ with\ spaces/textfile
Run Code Online (Sandbox Code Playgroud)

你看到你必须在路径或文件名中转义空格 - 或者引用它们。上面的行等于下面的行:

grep "I like Ubuntu" "/home/you/path with spaces/textfile"
Run Code Online (Sandbox Code Playgroud)