我有一个关于ls
命令的基本问题。
假设在一个目录中我有4个名为
run
run1
running
run.sh
所以,如果我这样做:ls -l|grep run*
那么我就没有结果。
但如果我ls -l|grep run.*
,那么我会得到run.sh
。
但是我希望grep
列出两种情况下的所有文件。
你能让我明白幕后发生的事吗?
答案 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*
搜索当前目录中的文件,并查找run
,run1
,running
和run.sh
。然后它用这些参数重写grep
命令:
ls -l | grep run run1 running run.sh
会导致grep
搜索字符run1
running
,run.sh
和run
。
如上所述,解决方案是将参数引用到grep
,以便shell不会尝试对其执行文件名扩展:
ls -l | grep 'run.*'