我有包含特定模式的文件列表,但这些文件已被涂焦。现在我想在tar文件中搜索模式,并且知道哪些文件包含模式而不提取文件。
任何想法......?
答案 0 :(得分:35)
tar
命令有一个-O
开关,用于将文件提取到标准输出。因此,您可以将这些输出传递给grep/awk
tar xvf test.tar -O | awk '/pattern/{print}'
tar xvf test.tar -O | grep "pattern"
例如,返回文件名,找到一个模式
tar tf myarchive.tar | while read -r FILE
do
if tar xf test.tar $FILE -O | grep "pattern" ;then
echo "found pattern in : $FILE"
fi
done
答案 1 :(得分:22)
答案 2 :(得分:7)
GNU tar
有--to-command
。有了它,您可以tar
将存档中的每个文件传输到给定命令中。对于您只想要匹配的行的情况,该命令可以是简单的grep
。要知道文件名,您需要利用tar在命令环境中设置某些变量;例如,
tar xaf thing.tar.xz --to-command="awk -e '/thing.to.match/ {print ENVIRON[\"TAR_FILENAME\"] \":\", \$0}'"
因为我发现自己经常使用这个,所以我有这个:
#!/bin/sh
set -eu
if [ $# -lt 2 ]; then
echo "Usage: $(basename "$0") <pattern> <tarfile>"
exit 1
fi
if [ -t 1 ]; then
h="$(tput setf 4)"
m="$(tput setf 5)"
f="$(tput sgr0)"
else
h=""
m=""
f=""
fi
tar xaf "$2" --to-command="awk -e '/$1/{gsub(\"$1\", \"$m&$f\"); print \"$h\" ENVIRON[\"TAR_FILENAME\"] \"$f:\", \$0}'"
答案 3 :(得分:2)
Python的tarfile
module和Tarfile.extractfile()
将允许您检查tarball的内容而不将其提取到磁盘。
答案 4 :(得分:2)
最简单的方法可能是使用avfs。我之前用过这个来完成这些任务。
基本上,语法是:
avfsd ~/.avfs # Sets up a avfs virtual filesystem
rgrep pattern ~/.avfs/path/to/file.tar#/
/path/to/file.tar
是实际tar文件的路径。
预挂起~/.avfs/
(挂载点)和附加#允许avfs将tar文件公开为目录。
答案 5 :(得分:1)
这可以通过 tar --to-command
和 grep --label
完成:
tar xaf archive.tar.gz --to-command 'egrep -Hn --label="$TAR_FILENAME" your_pattern_here || true'
--label
为 grep 提供文件名-H
告诉 grep 显示文件名和 -n
行号|| true
因为否则如果找不到模式,grep 将退出并显示错误,tar
会抱怨。xaf
表示根据文件扩展名提取并自动解压缩--to-command
让 tar 将 tarfile 中的每个文件传递给 grep 的单独调用,并使用有关文件的信息设置各种环境变量。有关详细信息,请参阅 the manpage。很大程度上基于 Chipaca's answer(和 Daniel H 的评论),但这应该更容易使用,并且只使用 tar 和 grep。
答案 6 :(得分:0)
使用ugrep选项-z
实际上很容易:
-z, --decompress
Decompress files to search, when compressed. Archives (.cpio,
.pax, .tar, and .zip) and compressed archives (e.g. .taz, .tgz,
.tpz, .tbz, .tbz2, .tb2, .tz2, .tlz, and .txz) are searched and
matching pathnames of files in archives are output in braces. If
-g, -O, -M, or -t is specified, searches files within archives
whose name matches globs, matches file name extensions, matches
file signature magic bytes, or matches file types, respectively.
Supported compression formats: gzip (.gz), compress (.Z), zip,
bzip2 (requires suffix .bz, .bz2, .bzip2, .tbz, .tbz2, .tb2, .tz2),
lzma and xz (requires suffix .lzma, .tlz, .xz, .txz).
例如:
ugrep -z PATTERN archive.tgz
这使每个已存档文件都显示为PATTERN
与已存档文件名匹配。归档文件名用大括号显示,以区别于普通文件名。其他所有内容与grep
相同(ugrep具有相同的选项并产生相同的输出)。例如:
$ ugrep -z "Hello" archive.tgz
{Hello.bat}:echo "Hello World!"
Binary file archive.tgz{Hello.class} matches
{Hello.java}:public class Hello // prints a Hello World! greeting
{Hello.java}: { System.out.println("Hello World!");
{Hello.pdf}:(Hello)
{Hello.sh}:echo "Hello World!"
{Hello.txt}:Hello
如果只需要文件名,请使用选项-l
(--files-with-matches
)并使用选项--format="%z%~"
自定义文件名输出以删除花括号:
$ ugrep -z Hello -l --format="%z%~" archive.tgz
Hello.bat
Hello.class
Hello.java
Hello.pdf
Hello.sh
Hello.txt
棒球(.tar.gz
/ .tgz
,.tar.bz2
/ .tbz
,.tar.xz
/ .txz
,.tar.lzma
/ {{1 }})以及.tlz
档案中进行搜索。