【发布时间】:2014-11-11 06:00:02
【问题描述】:
当使用ls | grep *e* 时,结果比ls | grep e 小得多,为什么会这样。它们是不是相同的命令。任何人都知道这些命令之间的区别。
【问题讨论】:
当使用ls | grep *e* 时,结果比ls | grep e 小得多,为什么会这样。它们是不是相同的命令。任何人都知道这些命令之间的区别。
【问题讨论】:
ls | grep *e*和ls | grep e不是同一个命令吗?
不,它们是不同的。与
$ ls | grep *e*
command shell 扩展模式*e* 以匹配当前目录中包含字母e 的所有文件。然后将此展开的文件列表传递给grep 命令:
$ ls
Hello.txt Null.txt Sample.txt
执行时
$ ls | grep *e*
实际的命令是ls | grep Hello.txt Sample.txt
与
$ ls | grep e
没有文件名扩展,实际命令为ls | grep e。
另见
如果要传递参数而不被扩展,则需要引用它:
$ ls | grep "*e*"
然后,该命令实际上将是 ls | grep *e*("*e*" 作为 argv[1] 传递给 grep 命令)。
请注意,shell 扩展与正则表达式不同——shell 匹配 * 的任何字符串,而在正则表达式中,* 表示将出现任意数量的先前表达式。
【讨论】:
shell 在执行命令之前扩展*e*。因此,如果您有名为beer 和free 的文件,您最终会在free 中搜索beer,并忽略来自ls 的输入。
*e* 无论如何都不是有效的正则表达式。 * 表示“零个或多个前面的表达式”,第一个实例中没有前面的表达式。正确地,grep 应该为此显示错误,但不会。它最终不匹配任何重复零次或多次的内容,然后是 e 重复零次或多次。因为每个可以想象的输入都包含零次或多次出现的e,所以它最终会匹配每个输入行。
但无论如何,如上所述,grep 不会看到这个输入,因为它被 shell 拦截和扩展。如果你想从字面上使用*,你需要引用它。
ls | grep '.*e.*'
只是一种很蹩脚的说法
ls | grep 'e'
因为前导通配符和尾随通配符没有任何价值 -- grep 总是在每个输入行的任意位置查找匹配项。
你真正想要的是使用shell的通配符匹配功能:
ls *e*
glob 表达式*e* 不是正则表达式,而是glob 模式。它可以满足您的预期。
【讨论】: