何时在 grep 中使用单引号、双引号或不使用引号?

23 unix shell grep command unix-shell

在尝试在文件中搜索简单模式“hello”时,以下所有形式的 grep 都有效:

  • grep你好文件1
  • grep“你好”文件1
  • grep“你好”文件1

是否存在上述形式之一有效但其他形式无效的特定情况。如果我用一个代替另一个有什么区别吗?

Jam*_*ger 29

这实际上取决于您的外壳。引号(任何一种)主要用于处理空格。例如,以下内容:

grep hello world file1
Run Code Online (Sandbox Code Playgroud)

将在名为“world”和“file1”的文件中查找单词“hello”,而

grep "hello world" file1
Run Code Online (Sandbox Code Playgroud)

将在文件 1 中查找“hello world”。

仅当搜索字符串包含您希望评估的变量或其他项目时,单引号或双引号之间的选择才重要。使用单引号,字符串按字面意思进行,不会发生扩展。使用双引号,变量被扩展。例如(使用 Bourne 派生的 shell,如 Bash 或 ZSH):

VAR="serverfault"
grep '$VAR' file1
grep "$VAR" file1
Run Code Online (Sandbox Code Playgroud)

第一个grep将在 file1 中查找文字字符串“$VAR1”。第二个将扩展“$VAR”变量并在文件 1 中查找字符串“serverfault”。

  • 在那里小心点。`$` 是正则表达式中的行尾,因此 `$VAR1` 不应该实际匹配任何内容。它恰好适用于 GNU grep,但我仍然不会指望这种行为。您需要 `\$VAR1` 来安全地匹配文字字符串。(如果是双引号,则需要额外的反斜杠。) (2认同)

wfa*_*ulk 7

James 是正确的,但要添加更多数据,我认为最好的思考方式是将其作为命令的参数:您打算将“hello”和“world”作为两个参数还是将“hello world”作为一个参数?争论。

此外,双引号允许解释的不仅仅是变量。具体取决于您的 shell,但请检查历史扩展、大括号扩展和文件名扩展。

同样重要的是要注意,在某些情况下,您需要在单个参数中使用两种类型的引号。请记住(默认情况下)参数由空格分隔,因此如果您不留任何空格,您仍然指定相同的参数。

大多数 shell 的单引号机制不允许任何特殊字符,这意味着另一个单引号的任何实例,即使它看起来被转义,也会结束引号。因此,不可能在单引号字符串中传递带有单引号的字符串,您必须使用双引号。当您想传递一个包含单引号和一些将被解释的参数的参数时,这可能会很痛苦,但您又不想这样。例如,如果你想传递文字字符串“`'​​$VAR' is a variable”,你必须这样做:

"'"'$VAR'"' is a variable"
Run Code Online (Sandbox Code Playgroud)

这实际上是三个引号转义字符串的串联:

"'"
'$VAR'
"' is a variable"
Run Code Online (Sandbox Code Playgroud)

或者,去掉引号:

'
$VAR
' is a variable
Run Code Online (Sandbox Code Playgroud)

实际上,对于大多数 shell,您也可以这样做:

"'\$VAR' is a variable"
Run Code Online (Sandbox Code Playgroud)

其中反斜杠 (" \") 告诉 shell 从字面上接受以下字符而不对其进行任何扩展。

但是在某些情况下,您最终不得不以多字符串连接的方式进行操作,而不是我现在实际上可以想出一个示例。