以通配符结尾的 grep 查找不合适的结果

grep ending with wildcard find results that are not suitable

我想查找所有以“libc”开头的文件。 例如,这些是我拥有的文件:

root@956b8809ab66:/test# ll
total 8
drwxr-xr-x 2 root root 4096 Apr  4 14:14 ./
drwxr-xr-x 1 root root 4096 Apr  4 14:14 ../
-rw-r--r-- 1 root root    0 Apr  4 14:14 libc
-rw-r--r-- 1 root root    0 Apr  4 14:14 libd
-rw-r--r-- 1 root root    0 Apr  4 14:14 libe

所以我使用了这个命令:

find .  -type f  | grep  "libc*"

我得到了不以“libc”开头的文件,例如:

root@956b8809ab66:/test# find .  -type f  | grep  "libc*"
./libd
./libe
./libc

不适合正则表达式中*的含义,也不适合glob结构。

那么为什么 grep return 这些结果?

作为@Janez Kuhar pointed out libc* is treated as a regex. It will match all as shown in this regex demo


如果您希望 find 仅将 libc* 显示为 glob,我建议使用 -iname

find . -type f -iname "libc*"

作为 的补充:

So does it mean that there is not different between "libc*" and "liba*" or "libf*"?

* 正则表达式量词指出:

matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)

所以是的,libc*liba*libf* 都会给出相同的结果,因为您仍然说最后一个字符 (a/f) 是可选的,因此 lib 将匹配。

Tl;dr 版本:使用 find . -type f -name 'libc*'

有几件事会给您带来一些困难;让我们假设您的发现为您提供了以下(假设的)结果。

$ find . -type f
./meh/library/alfa.py
./meh/bravolib/bravo.rb
./meh/libcharlie/charlie.c
./meh/libs/libc.so
./meh/libs/libm.so
./meh/mike/mikeslibc.so

你的 `grep libc*' 将 return 这些行中的每一行。 grep 本质上是说给你每一行 'lib' 后跟零个或多个 c。上面的每一行都满足这个条件。

如果你想挽救你的 grep,你可以做几件事:

  • 将*改为.*;有了这个而不是匹配前一个字符的零个或多个,你将匹配任何字符的零个或多个;句号代表任何字符。
  • 在 libc 之前检查一个 /;这将过滤掉像'./mikeslibcstuff.so'
  • 这样的东西
  • 而不是检查 任何东西 检查任何不包含正斜杠的东西;本质上是 [^/]* 而不是 .*.
  • 使用 $.
  • 将模式锚定到字符串的末尾
  • grep '/libc[^/]$ 可能会给您想要的结果。

现在;尽管如此,您实际上是在尝试将方钉放入圆孔中。在这种情况下,Grep 并不是真正适合这项工作的工具。正确的工具是使用带有 -name 或 -iname 标志的 find 内置的文件名通配符匹配功能:

$ find . -name 'libc*'