我在使用 一次性搜索所有目录时遇到问题grep
。当我使用以下命令时:
find . -name "*.txt" | xargs grep texthere
它只是花了很长时间然后给我“没有这样的文件或目录”的错误。
为什么会发生这种情况?还有什么比这更简单的吗grep
?还是我使用了错误的命令?
答案1
如果您有 GNU grep,grep 本身支持“-r”选项进行递归搜索,如@Ouroborus 所建议的那样。
如果不幸的是你的 grep 不支持这样的选项,比如在 SunOS 中,你可以使用以下命令代替:
find . -name "*.txt" -exec grep -n your_pattern {} /dev/null \;
增加了一个技巧/dev/null
,确保每次执行 grep 时都会提供两个文件(匹配到的 *.txt 文件和 /dev/null),从而强制它打印正在搜索的文件的名称。您还可以添加-type f
选项find
来细化 的范围find
。
答案2
就像这个答案,你最好这样做:
grep -rnw '/path/to/somewhere/' -e "pattern"
-r
或者-R
是递归的,-n
是行号,并且-w
代表与整个单词匹配。-l
可以添加(小写 L)来仅给出匹配文件的文件名。
答案3
如果您收到有关权限的错误(您没有说您收到),那么我猜您要么站在根目录(/
)中,要么站在某个您无权读取所有文件的路径中,例如在/etc
或在中/var
。但是既然你说这需要很长时间,我更倾向于第一个假设(根目录)。
如果你想绝对搜索全部文件所有的系统,那么你做的就非常正确。将要不管你做什么,都要花很长时间。要搜索的文件实在太多了。
您可以使用find
它来缩小要查看的文件数量。
目前,您有
$ find . -name "*.txt" | xargs grep texthere
因为看起来您只对纯文本文件感兴趣,所以我们可以排除任何其他类型的文件(可执行文件):
$ find / -type f \! -perm -o=x -name "*.txt" | xargs grep texthere
我.
在/
这里替换了,因为这是我思考你是(如果我错了请纠正我)。我还指定我想要文件(-type f
)不可执行( \! -perm -o=x
) (!
需要进行转义,以免你的 shell 用它做一些奇怪的事情)。
现在,我们还可以做几件事。一个是安全问题,另一个可能是可能稍微提高一点速度。
有些文件名中可能包含空格,或者我们通常不希望在文件名中出现的奇怪字符。为了能够在find
和之间正确传递这些内容,grep
我们需要
$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 grep texthere
这 ( ) 表示每个文件名将由字符 ( ) 而不是空格字符-print0
分隔。接收这些以-delimited 格式的文件名的相应选项是。nul
\0
xargs
nul
-0
我认为是因为您没有使用这两个选项,所以才会出现“没有此文件或目录”的错误。
速度就是。如果您的搜索字符串是纯文本字符串且其中不包含正则表达式,则fgrep
此实用程序与您应使用的实用程序完全相同。grep -F
因此,如果您有一个纯文本字符串,并且想要在整个系统的每个文件中查找它:
$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 fgrep texthere
权限问题...显然有些文件您无法读取。您可以运行find
并fgrep
在sudo
这些文件前面添加:
$ sudo find ... | xargs -0 sudo fgrep texthere
或者您可以尝试制作另一个-perm
标志find
(并让它忽略您无法输入的目录),但这会太耗时并导致命令行太长,所以我不会在这里这样做。
或者你也可以只sudo -s
获取一个 root shell 并从那里运行它...但我一般不建议这么做,因为人们往往会忘记他们是谁,从而弄乱他们的系统root
。
另一种解决方案可以使用该locate
命令来查找.txt
整个系统上的所有文件。该locate
命令不搜索文件层次结构,而是使用数据库(通常每天更新,因此全部文件可能存在)。数据库只包含所有用户可访问的目录中的文件,因此如果您删除了自己目录的读取权限,那么您的文件将不存在于该目录中。
因此,find
用几乎等效的命令替换上面的命令locate
:
$ locate '*.txt' -0 | xargs -0 fgrep texthere
选项-0
(--null
在某些系统上为 或 )对应于--print0
选项find
。