grep:使用方括号匹配特定字符

grep:使用方括号匹配特定字符

所以我正在使用这个来尝试 grep 的强大功能资源

我目前遇到的问题是它似乎没有按我的预期工作。所以我有一个 demo.txt 文件,其中包含foo.txt,我使用这段代码来搜索它: grep [a-z][a-z]o.txt demo.txt但它返回空。zsh: no matches found: [a-z][a-z]o.txt 我想知道我对方括号使用的理解是否错误?

这是图片:

在此输入图像描述

答案1

因为您没有引用要传递给的正则表达式grep,所以它被 shell 捕获,并且 shell 尝试扩展它打电话grep。现在,您使用的正则表达式恰好也是有效的 shell glob 模式1,这意味着“列出当前文件夹中名称为任意两个字符,后跟字符串的所有文件或目录o.txt”。如果当前目录包含与该 glob 匹配的任何文件或子目录,则该 glob 将扩展到匹配的文件名:

$ ls
abo.txt  demo.txt

$ cat demo.txt
foo.txt

$ set -x
$ grep [a-z][a-z]o.txt demo.txt 
+zsh:7> grep abo.txt demo.txt

告诉显示它运行的实际命令set -xzsh如您所见,[a-z][a-z]o.txt扩展为匹配的文件名:abo.txt,并且是传递给 的内容grep

现在,您的目录中实际上没有任何匹配的文件名,这意味着zsh将模式扩展为空字符串,甚至grep根本没有启动。这就是错误的原因zsh: no matches found: [a-z][a-z]o.txt。那是 zsh 告诉您它无法将 glob 扩展到任何匹配的文件。

最后,如果您正确引用该模式,将会发生以下情况:

$ grep '[a-z][a-z]o.txt' demo.txt 
+zsh:12> grep '[a-z][a-z]o.txt' demo.txt
foo.txt

这次,引号保护了模式免受 shell 的影响,shell 通过了它按原样togrepgrep反过来将其解释为正则表达式,意思是“任意两个小写字母,然后是o,然后任何其他字符,并以“结尾txt。这是一个重要的细节,因为.在正则表达式中意味着“任何字符”。所以你真正想要的是:

grep '[a-z][a-z]o\.txt' demo.txt 

“转义\.”,.使其仅匹配文字点,不再表示“任何字符”。因此,请始终引用正则表达式并小心.

最后,这是使用扩展正则表达式编写此代码的另一种方法:

$ grep -E '[a-z]{2}o\.txt' demo.txt      
foo.txt

1参见正则表达式的定义是什么?有关 glob 与正则表达式的更多详细信息。

相关内容