如何通过压缩档案递归 grep?

xen*_*ide 17 grep find zip archive recursive

我试图找出use Test::Versioncpan 中有哪些模块。所以我习惯minicpan镜像它。我的问题是我需要遍历下载的档案,并 grep 档案中的文件。谁能告诉我我该怎么做?最好以一种方式告诉我存档中的哪个文件以及它在哪一行。

(注意:它们并非都是 tarball,有些是 zip 文件)

Gil*_*il' 19

好的,让我们应用 unix 哲学。这个任务的组成部分是什么?

  • 文本搜索:您需要一个工具来搜索文件中的文本,例如grep.
  • 递归:您需要一个工具来在目录树中查找文件,例如find.
  • 档案:您需要一个工具来阅读它们。

大多数 Unix 程序对文件进行操作。因此,要轻松地对归档组件进行操作,您需要将它们作为文件进行访问,换句话说,您需要将它们作为目录进行访问。

动静脉瘘文件系统呈现,每一个存档文件中的文件系统的观点/path/to/foo.zip是作为目录进行访问~/.avfs/path/to/foo/zip#。AVFS 提供对最常见存档文件格式的只读访问。

mountavfs
find ~/.avfs"$PWD" \( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
     -exec sh -c '
                  find "$0#" -name "*.pm" -exec grep "$1" {\} +
                 ' {} 'Test::Version' \;
fusermount -u ~/.avfs   # optional
Run Code Online (Sandbox Code Playgroud)

说明:

  • 挂载 AVFS 文件系统。
  • 在 中查找存档文件~/.avfs$PWD,这是当前目录的 AVFS 视图。
  • 对于每个存档,执行指定的 shell 片段(使用$0= 存档名称和$1= 要搜索的模式)。
  • $0#是存档的目录视图$0
  • {\}而不是{}在外部find替换{}内部-exec ;参数的情况下需要(有些做,有些不做)。
  • 可选:最后卸载 AVFS 文件系统。

或者在 zsh 中?4.3:

mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e\''
     reply=($REPLY\#/**/*.pm(.N))
'\')
Run Code Online (Sandbox Code Playgroud)

说明:

  • ~/.avfs$PWD/**/*.(tgz|tar.gz|zip) 匹配当前目录及其子目录的 AVFS 视图中的档案。
  • PATTERN(e\''CODE'\')将 CODE 应用于 PATTERN 的每个匹配项。匹配文件的名称在$REPLY. 设置reply数组会将匹配项转换为名称列表。
  • $REPLY\# 是档案的目录视图。
  • $REPLY\#/**/*.pm匹配.pm存档中的文件。
  • N如果没有匹配项,glob 限定符会使模式扩展为空列表。


xen*_*ide 2

看来我可以这样做

find authors/ -type f -exec zgrep "Test::Version" '{}' +  
Run Code Online (Sandbox Code Playgroud)

然而,这给出了如下结果:

authors/id/J/JO/JONASBN/Module-Info-File-0.11.tar.gz:Binary file (standard input) matches
Run Code Online (Sandbox Code Playgroud)

这对于 tarball 中的位置并不是很具体。希望有人能给出更好的答案。