【发布时间】:2020-02-19 18:26:53
【问题描述】:
上下文
假设我有两个文件 a.txt 和 b.txt 包含一些内容...
$ tail *.txt
==> a.txt <==
ABC
CDE
123
C
==> b.txt <==
C
321
EDC
CBA
让我们也想象一下,这些文件现在已经被放入一个 gzip 压缩包中......
$ tar -czf tarball.tgz *.txt
$ tar -tf tarball.tgz
a.txt
b.txt
目标
现在,我想对 tarball 中的文件进行 grep。在匹配之前看到原始文件名和行号会很好,但我最重要的是希望看到匹配的行。
我尝试了什么?
首先,我希望zgrep 'pattern' tarball.tgz 可以正常工作。它确实告诉我是否有匹配,它甚至可以计算它们,但我找不到打印匹配的方法......
$ zgrep 'AB' tarball.tgz
Binary file (standard input) matches
$ zgrep 'C' tarball.tgz
Binary file (standard input) matches
$ zgrep -c 'AB' tarball.tgz
1
$ zgrep -c 'C' tarball.tgz
6
其次,我想zcat tarball 并在其上使用常规 grep。但是,我仍然得到了完全相同的 “二进制文件(标准输入)匹配”消息......
$ zcat tarball.tgz | grep 'C'
Binary file (standard input) matches
我猜zcat(和zgrep)做了gunzip,但没有tar -xf?如果我查看zcat,我可以看到与刚刚完成tar -c 相同的输出...
$ zcat tarball.tgz
a.txt0000664�3���3���0000000001613554050266013370 0ustar useruserABC
CDE
123
C
b.txt0000664�3���3���0000000001613554050301013357 0ustar useruserC
321
EDC
CBA
$ tar -c *.txt
a.txt0000664�3���3���0000000001613554050266013370 0ustar useruserABC
CDE
123
C
b.txt0000664�3���3���0000000001613554050301013357 0ustar useruserC
321
EDC
CBA
所以最后,我得到了这个可以正常工作的解决方案:
$ tar -xOzf tarball.tgz | grep 'C'
ABC
CDE
C
C
EDC
CBA
当然,如果我现在询问文件名和行号,我没有得到任何有用的信息...
$ tar -xOzf tarball.tgz | grep -Hn 'C'
(standard input):1:ABC
(standard input):2:CDE
(standard input):4:C
(standard input):5:C
(standard input):7:EDC
(standard input):8:CBA
为了获得我想要的结果,我能想到的唯一方法是编写更多脚本来提取 tarball 并在循环中运行 grep...
有没有很好(简单而简洁)的方法来做到这一点?
【问题讨论】:
-
grep 不理解 tar 格式;它不会神奇地告诉您存档中的哪个单个文件匹配,不。提取文件并对其进行 grepping 是一种很好的方法。
-
哦! Unix stackexchange 上的This answer 可能会很有帮助。
-
确实@Shawn 这个答案有我需要的一切:添加
-a以获得快速而肮脏的方法,或使用此--to-command选项以获得最佳输出!您要发布答案吗?否则,我将在自己的答案中进行总结。 -
请注意,Stack Overflow 的范围仅限于关于编写代码的问题。当命令行 UNIX 工具不是“软件开发独有”的工具时,有关这些工具行为的问题更适合Unix & Linux。 Shawn 将您链接到那里的问题而不是 SO 上的问题是有原因的。
-
@Charles Duffy 这听起来很公平。我必须承认,我通常对哪些问题适合哪些 StackExchanges 感到困惑!那么,我们是否应该以不恰当的方式结束这个问题?