![UNIX 中 grep 的奇怪行为](https://linux22.com/image/1236530/UNIX%20%E4%B8%AD%20grep%20%E7%9A%84%E5%A5%87%E6%80%AA%E8%A1%8C%E4%B8%BA.png)
当我输入命令时
$ grep \\\\h junk
那么 shell 应该将 解释\\\\h
为\\h
- 因为每对\\
变成\
。 grep
反过来,应该将 解释\\h
为\h
变成\\
,\
因此应该在 中grep
搜索模式,并且它正在成功执行。 \h
junk
但它不工作\\\\$
。为什么?
答案1
要返回带有美元符号的行,另一种无需转义的方法是:
grep "[$]" file
查找包含文字的行\$
:
grep "[\][$]" file
答案2
仅返回带有美元符号的行。
grep "\\$" application/bootstrap.php
因为 $ 也是一个正则表达式命令(行尾),所以您必须引用它才能使双斜杠越过您的 shell 并进入 grep。
答案3
Grep 总是使用 \ 来引用下一个字符,因此 \h 在您的示例中简单地变成了 h,因为 \h 不是“特殊”的:
$ cat file
\a
a
$ grep \\a file
\a
a
$ grep \\\\a file
\a
答案4
\h 不是 grep 的特殊转义,因此 '\h' 应该在文件中找到 \h,并且确实如此。由于 \ 是特殊字符(键入ls \\
并显示 ls: : 因此这样的文件或目录),因此 shell 会在 grep 看到它之前删除第一个 \。因此,要在文件中匹配“\h”,请使用 grep \h 或 '\h' 以避免 shell 减少第一个 \ --> \。
现在 \$ : \ 被 shell 简化为 \,而 grep 看到 \$,并且因为 $ 在正则表达式中很特殊(如 +、.、* 等),\$ 是一个文字美元符号,正如一个简单的测试文件向您展示的那样。请参阅 re_format (7) 的手册页。因此,这会匹配所有带有美元符号的行。
因此,如果要在文件中匹配文字“\$”,我们需要考虑:\$ 被 shell 转义为文字 $,而 \ 被转义为:尝试ls \\\$' and you get "ls: \$: No such file or directory". So in
grep \\$ file , grep sees \$ and interprets that as $ again... So we want grep to see \\\$ (which it will unescape again to \$), so we can put single quotes around that and avoid headaches, or escape all the special characters for the shell too:
grep \\\\$ file`。这有效。
这就是为什么我几乎总是在第一个 grep 参数周围加上单引号,这样我就只需要考虑 grep 将做什么,而不用考虑 shell。