在tar文件中执行grep操作而不提取

时间:2010-03-09 06:46:16

标签: unix

我有包含特定模式的文件列表,但这些文件已被涂焦。现在我想在tar文件中搜索模式,并且知道哪些文件包含模式而不提取文件。

任何想法......?

7 个答案:

答案 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)

命令zgrep应该直接完成您想要的操作。

例如

zgrep "mypattern" *.gz

http://linux.about.com/library/cmd/blcmdl1_zgrep.htm

答案 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 moduleTarfile.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-commandgrep --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档案中进行搜索。