Unix'grep'用于所有子目录中所有gzip文件中的字符串


8

如何.gz在所有目录和子目录中的所有文件中递归grep字符串?

Answers:


13

@Steve Weet快要出现了。使用/ dev / null作为附加参数是强制显示文件名的一种好方法(我要记住,谢谢Steve),但是它仍然为找到的每个文件运行exec -这是一个巨大的开销。

您希望尽可能少地运行zgrep,以最大程度地利用每次执行:

find . -iname '*.gz' -print0 | xargs -0 zgrep PATTERN

xargs将为zgrep提供尽可能多的args(文件名),并重复执行它,直到它使用了find命令提供的所有文件为止。如果任何文件名或目录名中都有空格,使用-print0-0选项可使它正常工作。

在Mac OS X上,无需xargs即可达到相同的效果:

find . -iname '*.gz' -exec zgrep PATTERN {} +

+1太好了。我没有意识到xargs传递了多个参数。我的* nix命令行中的大多数命令都已经20岁了,我不认为xargs在20年前就这样做了。
史蒂夫·韦特

事实证明,在os / x上的查找与xargs的行为相同
Steve Weet 2010年

1
请参阅我对Steve Weet的答案的评论,该答案以-exec结尾的'+'结尾。
丹尼尔·安德森

使用-H总是至少有匹配的行显示文件名,在GNU的grep。
Daniel Andersson

1
$ zgrep --help
Usage: /bin/zgrep [OPTION]... [-e] PATTERN [FILE]...
Look for instances of PATTERN in the input FILEs, using their
uncompressed contents if they are compressed.

所以像

find . -iname "*.gz" -exec zgrep PATTERN {} \

-exec将为其迭代的每个文件生成一个zgrep的新实例,以防止您看到文件名。最好使用zgrep -r一棵树,或者-r不起作用,将查找结果的输出通过管道传递xargs zgrep
Noufal Ibrahim 2010年

我进入/bin/zgrep: -r: option not supported新安装的ubuntu系统。
aioobe

您可以xargs改为使用。
努法尔·易卜拉欣

请参阅我对Steve Weet的答案的评论,该答案以-exec结尾的'+'结尾。
丹尼尔·安德森

1

@aioobe快要出现了。该命令可以完成任务,但不会告诉您文件名

以下内容也应该告诉您文件名:

find . -iname "*.gz" -exec zgrep PATTERN {} /dev/null \;

的添加/dev/null将确保zgrep看到两个文件名,因此,如果找到字符串,它将为您显示文件名

编辑

进一步的研究表明,对于我的机器(OS / X)-exec,find参数将添加尽可能多的文件名(类似于xargs行为方式)。


太酷了,我对OSX并不了解-exec-我全都与可移植性有关,所以我不会在脚本中使用它,但是对于命令提示符非常有用。

对于其他版本的find,请使用“ +”代替“ \;” 默认情况下,结束exec语句的作用与OSX相同,此线程中的故事也是如此。请参见手册中的“ -exec命令{} +”。并非所有版本的都适用find,但大多数现代版本(例如,在基于Debian的发行版中)都是如此。
丹尼尔·安德森

使用-H总是显示,而不是与匹配线,在GNU的grep至少文件名,/dev/null黑客攻击。
Daniel Andersson

0

以下工作在 zsh

for archive in **/*.gz; do
    echo "[${archive}] "
    gzip -dc ${archive} | grep -n "String"
done

它也可能在工作bashksh等...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.