ved*_*edg 4 shell grep regular-expression wildcards
我创建了一个名为“T”的简单文本文件来测试以下异常行为grep:
1 Debug
2 debug
3 determined
4 Determined
Run Code Online (Sandbox Code Playgroud)
尝试了不同的语法:
$ grep De T
1 Debug
4 Determined
$ grep de T
2 debug
3 determined
$ grep Determined T
4 Determined
$ grep determined T
3 determined
$ grep Debug T
1 Debug
$ grep debug T
2 debug
$ grep [D]ebug T # Why result is 2-nd line???
2 debug
$ grep [Dd]ebug T # Why result is only one 2-nd line???
2 debug
$ grep [Dd]e T
1 Debug
2 debug
3 determined
4 Determined
$ grep [d]e T
2 debug
3 determined
$ grep [d]ebug T
2 debug
$ grep "[D]ebug" T
1 Debug
$ grep "[Dd]ebug" T
1 Debug
2 debug
$ grep [\D]ebug T # Why result is 2-nd line???
2 debug
$ grep --version
grep (GNU grep) 2.16
Run Code Online (Sandbox Code Playgroud)
正如你可以看到,几乎每一个grep的调用返回正确的结果,但是$ grep [D]ebug T,$ grep [Dd]ebug T,$ grep [\D]ebug T返回错误的结果。为什么会这样?
小智 7
我猜你可能debug在当前工作目录中有一个文件或目录:
$ ls -l
total 8
-rw-r--r-- 1 jay wheel 58 Feb 1 05:01 T
$ grep [D]ebug T
1 Debug
$ grep [Dd]ebug T
1 Debug
2 debug
$ touch debug
$ ls -l
total 8
-rw-r--r-- 1 jay wheel 58 Feb 1 05:01 T
-rw-r--r-- 1 jay wheel 0 Feb 1 05:05 debug
$ grep [D]ebug T
2 debug
$ grep [Dd]ebug T
2 debug
Run Code Online (Sandbox Code Playgroud)
我向你推荐了为什么你必须总是转义 shell 元字符的这个很好的说明。
更新以澄清正在发生的事情:我假设您像我一样使用具有不区分大小写的文件系统(例如 Mac)的操作系统。当您执行该命令时,您的 shell 在实际执行grep. 其中之一是文件名扩展,其中方括号提供替代:
[Dd]ebug在区分大小写的文件系统上将扩展为Debug debug,Debug或debug取决于它可以匹配的文件。由于它只匹配 file debug,您的命令变为:
grep debug T
Run Code Online (Sandbox Code Playgroud)
如果您删除该文件并执行touch Debug,您将看到命令的输出更改,因为它将被插入为
grep Debug T
Run Code Online (Sandbox Code Playgroud)
如果debug您的目录中没有该文件,您的 shell 会尝试插入括号,但在没有匹配的情况下失败,因此它碰巧传递参数不变。