Linux 如何在不占用磁盘空间的情况下在tar归档文件中grep模式

Linux 如何在不占用磁盘空间的情况下在tar归档文件中grep模式,linux,bash,shell,tar,Linux,Bash,Shell,Tar,我有一个非常大~5GB的焦油档案 我想在归档文件中的所有文件(以及打印具有该模式的文件的名称)上搜索模式,但不想通过提取归档文件来填充磁盘空间 反正我能做到 我尝试了这些,但这并没有给出包含模式的文件名,只有匹配的行: tar -O -xf test.tar.gz | grep 'this' tar -xf test.tar.gz --to-command='grep awesome' 此外,tar的这一特性在哪里有文档记录?tar xf test.tar$文件这里有一个可能适合您的bash函

我有一个非常大~5GB的焦油档案

我想在归档文件中的所有文件(以及打印具有该模式的文件的名称)上搜索模式,但不想通过提取归档文件来填充磁盘空间

反正我能做到

我尝试了这些,但这并没有给出包含模式的文件名,只有匹配的行:

tar -O -xf test.tar.gz | grep 'this'
tar -xf test.tar.gz --to-command='grep awesome'

此外,tar的这一特性在哪里有文档记录?tar xf test.tar$文件

这里有一个可能适合您的bash函数。将以下内容添加到
~/.bashrc

targrep () {
    for i in $(tar -tzf "$1"); do
        results=$(tar -Oxzf "$1" "$i" | grep --label="$i" -H "$2")
        echo "$results"
    done
}
用法:

targrep archive.tar.gz "pattern"
尝试:


t选项将在不提取文件的情况下测试tar文件。v是详细的,f打印文件名。这将为您节省大量硬盘空间。

这是一种令人难以置信的黑客行为,但您可能会滥用tar的
-v
选项来处理和删除提取的每个文件

grep_and_delete() {
  if [ -n "$1" -a -f "$1" ]; then
    grep -H 'this' -- "$1" </dev/null
    rm -f -- "$1" </dev/null
  fi
}
mkdir tmp; cd tmp
tar -xvzf test.tar.gz | (
  prev=''
  while read pathname; do
    grep_and_delete "$prev"
    prev="$pathname"
  done
  grep_and_delete "$prev"
)
grep_和_delete(){
如果[-n“$1”-a-f“$1”];则
grep-H'this'--“$1”
tar-tftest.tar.gz|grep-v'/$”|\
xargs-n1-I\u\
sh-c'tar-xOf test.tar.gz 124; grep-q&&echo 124;

以下是我对此的看法:

while read filename; do tar -xOf file.tar "$filename" | grep 'pattern' | sed "s|^|$filename:|"; done < <(tar -tf file.tar | grep -v '/$')

似乎没有人发布这个只处理存档一次的简单解决方案:

tar xzf archive.tgz --to-command \
    'grep --label="$TAR_FILENAME" -H PATTERN ; true'
这里,
tar
在一个变量中传递每个文件的名称(请参阅),它被
grep
用于打印每个匹配的文件。另外还添加了
true
,以便
tar
不会抱怨提取不匹配的文件失败。

可能会有所帮助

zcat log.tar.gz | grep -a -i "string"

zgrep -i "string" log.tar.gz


@opdecrkel tar的这一特性记录在哪里?tar xf test.tar$FILEGot to examples部分(最后一个示例):通常,
tar
的手册页甚至没有正确地解释附加文件……具体地说,是我的linux dist附带的手册页,
[pathname…]
并且没有进一步的解释,但是如果append有效(也没有文档),那么您也可以尝试提取……您必须阅读感谢Op!这非常有用!这不起作用。它打印(标准输入)作为文件名。我尝试使用-l和-H.Doh,在编写我的bash函数之前,我没有看到您的bash函数。您的bash函数比我的更好。:-+1。(现在我检查了一下,似乎FreeBSD的tar自动识别gzip文件,所以我的文件名识别可能是多余的。)这也不对。你在发布之前尝试过吗?有什么问题,@abc?它不提取文件;它在标准输出上获取文件名,并对它们进行greps。你得到了什么结果?或者是你想在不提取文件的情况下获取文件体中包含模式的文件名的问题。…这更难,但在问题中没有明确描述。这对于提取和搜索文件名模式非常有用。我发现它很有用,因为我只查找文件名。但是,说它不会搜索文件的内容是正确的。这种方法更快,因为它只解压缩
.tar.gz
文件e、 你能在原始帖子的评论中回答我的问题吗?@abc,如果这是你问题的一部分,你为什么不回答呢?我讨厌谢谢你,但这一个确实帮了我的忙-thx(:最佳答案,工作完美,符合tar的预期。
;true
对我不起作用;它们被作为参数传递给
grep
,grep抱怨
true
不是文件或目录。@DanielH您使用的是哪个shell?这可能会影响命令的解析和运行方式。
zsh
,但它似乎更像是在
tar
的版本之间而不是在shell之间发生变化的那种东西。
zsh
bash
都会以相同的方式解释单引号
grep
命令,如果直接输入的话。谢谢,这正是我想要的。其他答案在这里和相关的(dup?)问题多次阅读档案,或者看起来非常复杂。
targrep() {

  local taropt=""

  if [[ ! -f "$2" ]]; then
    echo "Usage: targrep pattern file ..."
  fi

  while [[ -n "$2" ]]; do    

    if [[ ! -f "$2" ]]; then
      echo "targrep: $2: No such file" >&2
    fi

    case "$2" in
      *.tar.gz) taropt="-z" ;;
      *) taropt="" ;;
    esac

    while read filename; do
      tar $taropt -xOf "$2" \
       | grep "$1" \
       | sed "s|^|$filename:|";
    done < <(tar $taropt -tf $2 | grep -v '/$')

  shift

  done
}
tar xzf archive.tgz --to-command \
    'grep --label="$TAR_FILENAME" -H PATTERN ; true'
zcat log.tar.gz | grep -a -i "string"

zgrep -i "string" log.tar.gz