如何通过 .gz 文件递归地 grep ?

如何通过 .gz 文件递归地 grep ?

我正在使用脚本定期下载 gmail 消息,将原始 .eml 压缩为 .gz 文件。该脚本为每天创建一个文件夹,然后将每条消息压缩到其自己的文件中。

我想要一种在这个档案中搜索“字符串”的方法。

仅 Grep 似乎无法做到这一点。我也尝试过SearchMonkey。

答案1

如果要在当前目录中的所有 .eml.gz 文件中递归地 grep ,可以使用:

find . -name \*.eml.gz -print0 | xargs -0 zgrep "STRING"

你必须转义第一个,*这样 shell 就不会解释它。-print0告诉 find 在找到的每个文件后打印一个空字符;xargs -0从标准输入读取并为每个文件运行其后的命令;zgrep与 类似grep,但首先解压缩文件。

答案2

这里有很多混乱,因为不只有一个zgrep。我的系统上有两个版本,zgrep来自gzipzgrep来自zutils。前者只是一个调用gzip -cdfq.不支持-r, --recursive切换。1
后者是一个c++程序,它支持选项-r, --recursive
运行zgrep --version | head -n 1将显示其中哪一个(如果有)是默认值:

zgrep (gzip) 1.6

是包装脚本,

zgrep (zutils) 1.3

cpp可执行文件。
如果你有后者,你可以运行:

zgrep 'pattern' -r --format=gz /path/to/dir

无论如何,正如所建议的,find+zgrep对于以下任一版本都同样适用zgrep

find /path/to/dir -name '*.gz' -exec zgrep -- 'pattern' {} +

如果zgrep您的系统中缺少(极不可能)您可以尝试:

find /path/to/dir -name '*.gz' -exec sh -c 'gzip -cd "$0" | grep -- "pattern"' {} \;

但有一个主要缺点:您不知道匹配项在哪里,因为匹配行前面没有文件名。


1:因为这会有问题

答案3

ag是 的变体 grep,具有一些不错的附加功能。

  • 对于压缩文件有 -z 选项,
  • 具有许多 ack 功能。
  • 它很快

所以:

ag -r -z your-pattern-goes-here   folder

如果没有安装,

apt-get install silversearcher-ag   (debian and friends)
yum install the_silver_searcher     (fedora)
brew install the_silver_searcher    (mac)

(2021 年 9 月编辑 \谢谢(x-yuri))

还要考虑rg(递归 grep),它有-z选项

rg -z your-pattern-goes-here   folder

rg 还有大量有用的选项。如有必要:

apt install ripgrep 

答案4

单独递归很容易:

   -r, --recursive
          Read all files  under  each  directory,  recursively,  following
          symbolic  links  only  if they are on the command line.  This is
          equivalent to the -d recurse option.

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

但是,对于压缩文件,您需要类似以下内容:

shopt globstar 
for file in /path/to/directory/**/*gz; do zcat ""$file" | grep pattern; done

path/to/directory应该是包含每天的子目录的父目录。


zgrep是显而易见的答案,但不幸的是,它不支持该-r标志。从man zgrep

这些 grep 选项将导致 zgrep 终止并显示错误代码:(-[drRzZ]|--di*|--exc*|--inc*|--rec*|--nu*)。

相关内容