在一个文件夹中查找压缩为gz格式的文件中的字符串。

48

我目前的问题是有大约10个文件夹,其中包含gzipped文件(平均每个文件夹有5个)。这使得需要打开并查看50个文件。

是否有更简单的方法来确定文件夹中的gzipped文件是否具有特定的模式?

zcat ABC/myzippedfile1.txt.gz | grep "pattern match"
zcat ABC/myzippedfile2.txt.gz | grep "pattern match"

我是否可以一行代码完成对所有文件夹及其子文件夹相同操作的任务,而无需编写脚本?

for f in `ls *.gz`; do echo $f; zcat $f | grep <pattern>; done;
8个回答

55

zgrep可以查找gzip压缩文件,具有-R递归选项和-H显示文件名选项:

zgrep -R --include=*.gz -H "pattern match" .

由于不是所有的参数都适用于所有操作系统,因此需要使用特定于操作系统的命令:

Mac 10.5+:zgrep -R --include=\*.gz -H "匹配模式" .

Ubuntu 16+:zgrep -i -H "匹配模式" *.gz


19
我的 zgrep 不支持 -R 选项。 - ZombieDev
@Ned Batchelder,感谢您提供方向。但对我来说,以下命令可以使用zgrep选项“pattern”文件。 - Hiren
1
在zsh上执行以下命令:zgrep -R --include=\*.gz -H "pattern" - blacktooth
7
Ubuntu 12.04 LTS 上最新版本的 gzip 工具 zgrep 不包含 -R 选项。 - sorin
3
同样在Ubuntu 14.04 LTS上:“-R:选项不受支持”。 - mork
在 Mac 终端上,include 似乎也不受支持 /sw/bin/zgrep: --include=*.gz: option not supported - Anupam

21
你不需要在这里使用zcat,因为有zgrepzegrep。如果你想在一个目录层次结构中运行一个命令,可以使用find
find . -name "*.gz" -exec zgrep ⟨pattern⟩ \{\} \;

而且在 for 循环中,“ls *.gz” 是无用的,未来应该只使用“*. gz”。


我通过这种方法获取包含此模式的行,但无法获取文件名。有没有办法将文件名也列出来? - gagneet
2
find . -name '*.gz' -print0 | xargs -0 zgrep pattern - Hasturkun
2
老的 grep 技巧:find . -name "*.gz" -exec zgrep ⟨pattern⟩ /dev/null {} ; # 这将使 grep 认为有多个文件并打印文件名。 - Aaron Digulla
这并没有告诉我它在哪个文件中找到了该模式。 - Kalpesh Soni

11

如何让zgrep不支持-R选项

我认为"Nietzche-jou"的解决方案可能是更好的答案,但我想添加-H选项以显示文件名,就像这样

find . -name "*.gz" -exec zgrep -H 'PATTERN' \{\} \;

是的,这个命令实际上还显示了文件名。 - Umair Ayub

8

使用查找命令

find . -name "*.gz" -exec zcat "{}" + |grep "test"

或者尝试使用zcat的递归选项(-r)


-bash-3.00$ find . -name "*.gz" -exec zcat "{}" + | grep "NOT OK" find: 在 `-exec' 之后缺少参数 似乎缺少一些东西在 exec 后面? - gagneet
也许尝试更改为find ... +; | grep ...并查看。 - ghostdog74
你必须使用分号“;”来终止“-exec”选项。 - Aaron Digulla
"find -exec cmd {} +" 相对较新,因此如果您使用的是旧版本的 find,则可能不支持“+”。它类似于“find -print0 | xargs -0 cmd”。 - mark4o
它可以工作。 :) 只是想知道如何获取匹配字符串的文件名。上面的命令只提供具有匹配字符串的行。 - Suvasis

7

稍微晚了一点,我也遇到过类似问题,但通过以下方法解决:

zcat -r /some/dir/here | grep "blah"

如此详细地阐述在这里:

http://manpages.ubuntu.com/manpages/quantal/man1/gzip.1.html

然而,这并不显示匹配结果来自哪个原始文件,而是显示“(standard input)”,因为它是从管道中输入的。zcat似乎也不支持输出名称。

就性能而言,我们得到了以下结果:

$ alias dropcache="sync && echo 3 > /proc/sys/vm/drop_caches"

$ find 09/01 | wc -l
4208

$ du -chs 09/01
24M

$ dropcache; time zcat -r 09/01 > /dev/null
real    0m3.561s

$ dropcache; time find 09/01 -iname '*.txt.gz' -exec zcat '{}' \; > /dev/null
0m38.041s

如您所见,使用find|zcat方法处理即使是小量的文件也比使用zcat -r慢得多。我也无法让zcat输出文件名(使用-v会在某些行中输出文件名,但不是每一行)。目前似乎没有工具可以同时提供速度和与grep一致的名称(即-H选项)。
如果您需要确定结果所属的文件名,则需要编写自己的工具(50行Python代码即可完成)或使用较慢的方法。如果您不需要确定名称,则使用zcat -r
希望这能帮到您。

2

find . -name "*.gz"|xargs zcat | grep "pattern"应该可以完成。


该命令用于在当前目录及其子目录中查找所有以".gz"结尾的文件,然后解压缩并搜索其中包含"pattern"的内容。

2

zgrep "string" ./*/*

您可以使用上述命令在dir目录下的.gz文件中搜索string,其中dir具有以下子目录结构:

/dir
    /childDir1
              /file1.gz
              /file2.gz
    /childDir2
              /file3.gz
              /file4.gz
    /childDir3
              /file5.gz
              /file6.gz

0

你可以使用这个命令 -

zgrep "foo" $(find . -name "*.gz")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接