Shell UNIX:grep外卡

时间:2014-02-01 01:06:59

标签: bash shell unix grep wildcard

我无法弄清楚为什么在以下示例中使用grep:

对野生字符*进行不同的解释
find . -type f -name \*

结果:

./tgt/etc/test_file.c
./tgt/etc/speleo/test_file.c
./tgt/etc/other_file.c
./src/file.c

我想从此命令返回与模式匹配的文件,最终使用通配符*。但是:

find . -type f -name \* | grep "tgt/etc/*" # this one works
find . -type f -name \* | grep tgt/etc/* # not this one
find . -type f -name \* | grep tgt/et*/s* # this one works
find . -type f -name \* | grep "tgt/et*/s*" # not this one

我希望有一个适用于这两种情况的实现。我该怎么用?

3 个答案:

答案 0 :(得分:5)

grep的第一个参数不是通配符,而是正则表达式。在正则表达式中,*表示匹配其前面的任何数字的字符或表达式。所以

grep "tgt/etc/*"

表示匹配tgt/etc后跟零个或多个/个字符。在通配符中,*表示匹配任意数量的任何字符,等效的正则表达式为.*。出于您的目的,您需要的命令是:

find . -type f -name \* | grep "tgt/etc/"
find . -type f -name \* | grep "tgt/et.*/s"

此外,如果您不引用参数,并且它包含任何*个字符,那么shell会将参数扩展为文件名通配符,然后将它们作为参数传递给grep。所以当你写:

find . -type f -name \* | grep tgt/etc/*

shell会将其扩展为

find . -type f -name \* | grep tgt/etc/file1 tgt/etc/file2 tgt/etc/file3

这会将tgt/etc/file1视为要搜索的正则表达式,并在剩余文件中查找它 - 它将处理来自管道的输入,因为它已被给出文件名参数。

答案 1 :(得分:3)

"看到它们之前,shell会扩展未加引号的示例(没有grep)。这就是Unix shell工作的方式。

对于引用的,请注意grep模式中的*意味着与shell和find的含义不同:它意味着“重复前面的字符任意次(包括零)。”

答案 2 :(得分:1)

因为grep使用正则表达式而没有通配符。

基本上,你要做的是:

  • tgt/etc/*检查零或sereval /
  • tgt/et*/s*检查零个或多个t和零个或多个s

但事实是,当你没有在正则表达式周围加上引号时,shell会将*扩展为通配符,这会使grep看到的正则表达式变得混乱。