几十年来,我一直很喜欢使用 'grep',但几年后我离开了 Linux,然后又回来了,发现 'grep' 的工作方式与以前不同。我从网上检查了它的用法,确认我的记忆没有被破坏。
我确信某些*.h
文件*.cpp
位于更深的子目录下。我使用了以下命令并得到了意想不到的类似结果:
grep 44738 -r -l *.h
grep 44738 -r -l *.c
grep 44738 -r -l *.c*
我得到了结果
grep: *.h: No such file or directory
./daemons/snmpcd/snmpcd.cpp
./.svn/pris.......svn-base
grep: *.c: No such file or directory
./daemons/snmpcd/snmpcd.cpp
./.svn/pris.......svn-base
grep: *.c*: No such file or directory
./daemons/snmpcd/snmpcd.cpp
./.svn/pris........svn-base
分别。
- 如果我使用命令:
grep 44738 -r -l .
,我会得到相同的结果,除了第一行grep: ...
- 如果我使用命令:
grep 44738 -r -l *.c*
,则只会得到grep: ...
没有任何文件。 - 如果我使用命令:
grep 44738 -r -l -file *.c* .
,我只会得到grep: *.c*: No such file or directory
结果几乎与我几年前的经历相反。我的问题是:
- ubuntu-18.04.6 有很多变化吗
grep
? - 如何在 grep 中指定文件模式?为什么我不能像几年前那样使用
*.c
诸如之类的模式?*.h
*.c*
- 我的同事建议我使用
ack
,但我发现几乎相同的事情。我应该使用什么命令进行全局字符串搜索grep
?
答案1
这里有两个问题。首先,您不能组合-r
或-R
标志,也不能将目标文件名作为参数。/-r
启用-R
递归搜索,这意味着“搜索给定目录中的所有文件”,因此它们会将grep
其参数视为要在其中查找文件的目录。由于没有名称与*.c*
glob 匹配的目录,因此您会得到显示的错误。据我所知,这种情况一直存在,至少自从我使用 Linux 以来,已经快 25 年了。
-r
如果你不使用/-R
标志,你可以随意使用 glob ,但您必须将它们引用起来,这是必要的。如果您没有像您所做的那样引用它,则 shell 会将 glob 扩展为任何匹配的文件,并且grep
将看不到 glob,而只能看到 shell 对其进行扩展的结果,因此只能看到当前目录中名称与 glob 匹配的任何文件或目录。
现在,grep
Linux 上的默认 GNU 有一种方法可以做你想做的事情,但是语法不同:
grep 44738 -r -l --include='*.h'
看man grep
:
--include=GLOB
Search only files whose base name matches GLOB (using wildcard
matching as described under --exclude). If contradictory
--include and --exclude options are given, the last matching
one wins. If no --include or --exclude options match, a file
is included unless the first such option is --include.