Wya*_*ant 10 shell bash quoting regular-expression
为什么
grep e\\.g\\. <<< "this is an e.g. wow"
Run Code Online (Sandbox Code Playgroud)
和
grep e\.g\. <<< "this is an e.g. wow"
Run Code Online (Sandbox Code Playgroud)
做同样的事?
如果我添加第三个斜杠,它也有相同的结果。但是,一旦我添加了第四个斜线,它就不再起作用了。这与一个班级旧考试中的问题有关。它询问带有两个反斜杠的一个是否可以输出带有“eg”的行,我最初认为它不起作用,但我试图确定并且确实如此。解释是什么?
首先,请注意单斜杠匹配太多:
$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
e.g.
Run Code Online (Sandbox Code Playgroud)
就Bash而言,转义句点与句点相同。Bash 将句号传递给grep。对于 grep,句点匹配任何内容。
现在,考虑:
$ echo $'eegg \n e.g.' | grep e\\.g\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\.g\\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\\.g\\\\.
$
Run Code Online (Sandbox Code Playgroud)
当 Bash 看到双斜线时,它会将其减少为单斜线并将其传递给 grep,在上述三个测试中的第一个测试中,如我们所愿,在句点之前看到一个单斜线。因此,这是正确的。
通过三重斜线,Bash 将前两个斜线减少为一个斜线。然后它看到\.。由于转义句点对 Bash 没有特殊意义,因此将其简化为普通句点。结果是 grep 如我们所愿,在句点前看到一个斜线。
Bash 使用四个斜线将每一对减少为一个斜线。Bash 传递给 grep 两个斜杠和一个句点。的grep看到两条斜线和一个周期,并降低了两个斜杠到单个字面斜线。除非输入有一个斜杠后跟任何字符,否则没有匹配项。
为了说明最后一点,请记住在单引号内,所有字符都是字面量。因此,给定以下三个输入行,grep 命令仅匹配输入中带有斜杠的行:
$ echo 'eegg
e.g.
e\.g\.' | grep e\\\\.g\\\\.
e\.g\.
Run Code Online (Sandbox Code Playgroud)
对于 Bash,规则是
两个斜线减少为一个斜线。
普通字符前面的斜线,如句号,就是普通字符(句号)。
因此:
$ echo \. \\. \\\. \\\\.
. \. \. \\.
Run Code Online (Sandbox Code Playgroud)
有一个简单的方法可以避免所有这些混淆:在 Bash 命令行中,正则表达式应该放在单引号中。在单引号内,Bash 将所有内容都放在一边。
$ echo '\. \\. \\\. \\\\.' # Note single-quotes
\. \\. \\\. \\\\.
Run Code Online (Sandbox Code Playgroud)