grep filename [星号]返回意外结果

时间:2013-12-09 14:46:07

标签: regex shell grep glob

我有一个关于ls命令的基本问题。 假设在一个目录中我有4个名为

的文件
run
run1
running
run.sh

所以,如果我这样做:ls -l|grep run*那么我就没有结果。

但如果我ls -l|grep run.*,那么我会得到run.sh

但是我希望grep列出两种情况下的所有文件。 你能让我明白幕后发生的事吗?

3 个答案:

答案 0 :(得分:3)

这是因为星号对于shell来说是特殊的并且会被扩展。为了避免这种情况,你必须引用grep的正则表达式来看它未扩展:

ls -l|grep 'run*'

请注意,这不是您想要的,因为'run *'作为正则表达式意味着'ru后跟任意数量的n'。这将列出名为rubber的文件,依此类推。要列出与 shell glob模式匹配的文件(与regexp不同),为什么不简单地使用

ls -l run*
ls -l run.*

完全避免使用无用的grep进程?

答案 1 :(得分:2)

只要我理解,在执行命令本身之前,shell会扩展“*”,因此你的grep将尝试捕获包含所有文件名的字符串!另一方面,grep需要一个正则表达式,因此“*”不会按预期解释。

直接的解决方案是:

$ ls -l run*

或者,如果你想使用grep,那么scape“*”并提供一个正则表达式:

$ ls -l|grep run.\*
$ ls -l|grep 'run.*'

答案 2 :(得分:1)

在shell运行grep之前,它会在命令中搜索任何未加引号的文件通配字符,并对这些参数执行文件名扩展。

所以当你输入这个命令时:

ls -l | grep run*

shell使用模式run*搜索当前目录中的文件,并查找runrun1runningrun.sh。然后它用这些参数重写grep命令:

ls -l | grep run run1 running run.sh

会导致grep搜索字符run1 runningrun.shrun

如上所述,解决方案是将参数引用到grep,以便shell不会尝试对其执行文件名扩展:

ls -l | grep 'run.*'