以通配符结尾的 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*'
我想查找所有以“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*'