我无法弄清楚为什么在以下示例中使用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
我希望有一个适用于这两种情况的实现。我该怎么用?
答案 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看到的正则表达式变得混乱。