【问题标题】:find string inside a gzipped file in a folder在文件夹中的 gzip 文件中查找字符串
【发布时间】:2010-11-18 05:41:09
【问题描述】:

我目前的问题是我有大约 10 个文件夹,其中包含 gzip 文件(平均每个大约 5 个)。这使得它可以打开和查看 50 个文件。

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

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;

【问题讨论】:

    标签: linux shell directory grep gzip


    【解决方案1】:

    你可以使用这个命令-

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

    【讨论】:

      【解决方案2】:

      zgrep 将查看 gzip 压缩文件,有一个 -R 递归选项和一个 -H 显示文件名选项:

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

      操作系统特定的命令并非所有参数都适用:

      Mac 10.5+: zgrep -R --include=\*.gz -H "pattern match" .

      Ubuntu 16+: zgrep -i -H "pattern match" *.gz

      【讨论】:

      • FWIW,我的 zgrep 不支持 -R
      • @Ned Batchelder,感谢您提供指导。但对我来说,遵循工作 zgrep 选项“模式”文件
      • zgrep -R --include=\*.gz -H "pattern" on zsh
      • zgrep (gzip) 1.4 -- Ubuntu 12.04 LTS 上的最新版本不包含 -R
      • 同样在 Ubuntu 14.04 LTS 上:“-R: option not supported”
      【解决方案3】:

      zgrep "string" ./*/*

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          来晚了,遇到了类似的问题,并且能够使用解决;

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

          这里详述;

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

          但是,这不会显示结果匹配的原始文件,而是显示“(标准输入)”,因为它来自管道。 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

          希望对你有帮助

          【讨论】:

            【解决方案6】:

            zgrep 怎么不支持 -R

            我认为“Nietzche-jou”的解决方案可能是一个更好的答案,但我会添加选项 -H 以显示类似这样的文件名

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

            【讨论】:

            • 是的,这也是实际显示文件名的命令
            【解决方案7】:

            这里不需要zcat,因为有zgrepzegrep。

            如果要在目录层次结构上运行命令,请使用 find:

            find . -name "*.gz" -exec zgrep ⟨pattern⟩ \{\} \;
            

            而且“ls *.gz”在for中也没用,以后你应该只使用“*.gz”。

            【讨论】:

            • 我得到了包含这个模式的行,但不是通过这个方法得到的文件名。有什么方法可以把它也列出来吗?
            • find . -name '*.gz' -print0 | xargs -0 zgrep pattern?
            • 旧 grep 技巧:查找 . -name "*.gz" -exec zgrep ⟨pattern⟩ /dev/null \{\} \; # 这会让 grep 认为有多个文件并打印文件名。
            • 这并没有告诉我它在哪个文件中找到了该模式
            【解决方案8】:

            使用查找命令

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

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

            【讨论】:

            • -bash-3.00$ 查找 . -name "*.gz" -exec zcat "{}" + | grep "NOT OK" find: missing argument to `-exec' 在 exec 之后似乎缺少了什么?
            • 也许可以尝试更改查找... +; | grep ...看看
            • 您必须用“;”终止“-exec”选项
            • "find -exec cmd {} +" 相对较新,所以如果您有较旧的 find 它可能不支持“+”。类似于“find -print0 | xargs -0 cmd”。
            • 它有效。 :) 只是想知道我们如何获得匹配字符串的文件名。上面的命令只给出匹配字符串的行。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-07-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多