7

我有一个非常大的 tar 存档 ~ 5GB。

我想在存档中的所有文件上使用 grep 模式(并打印具有该模式的文件的名称),但不想通过提取存档来填满我的磁盘空间。

反正我能做到吗?

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

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

tar 的这个特性也在哪里记录?tar xf test.tar $文件

4

7 回答 7

13

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

tar xzf archive.tgz --to-command \
    'grep --label="$TAR_FILENAME" -H PATTERN ; true'

这里tar将每个文件的名称传递到一个变量中(请参阅文档),并用于grep在每次匹配时打印它。还true添加了,这样tar就不会抱怨无法提取不匹配的文件。

于 2013-06-26T19:25:44.280 回答
7

这是我对此的看法:

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

拆开解释:

  • while read filename; do——这是一个循环...
  • tar -xOf file.tar "$filename"-- 这会提取每个文件...
  • | grep 'pattern'-- 这里是你放置你的模式的地方......
  • | sed "s|^|$filename:|";- 前置文件名,所以这看起来像 grep。盐调味。
  • done < <(tar -tf file.tar | grep -v '/$')-- 结束循环,获取要发送到您的while read.

一个附带条件:如果您|的文件名中有 OR 条 ( ),这将中断。

唔。事实上,这是一个不错的 bash 小函数,您可以将其附加到.bashrc文件中:

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
}
于 2012-10-24T03:20:14.793 回答
3

这是一个可能对您有用的 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"
于 2012-10-23T23:57:49.347 回答
1

这是令人难以置信的hacky,但是您可以滥用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"
)
于 2012-10-24T00:12:00.053 回答
1
tar -tf test.tar.gz | grep -v '/$'| \
xargs -n 1 -I _ \
sh -c 'tar -xOf test.tar.gz _|grep -q <YOUR SEARCH PATTERN>  && echo _'
于 2012-10-24T00:30:54.660 回答
0

尝试:

    tar tvf name_of_file |grep --regex="pattern"

t 选项将测试 tar 文件而不提取文件。v 是详细的,f 打印他的文件名。这应该可以为您节省大量的硬盘空间。

于 2012-10-24T00:03:28.610 回答
0

可能有帮助

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

zgrep -i "string" log.tar.gz

http://www.commandlinefu.com/commands/view/9261/grep-compressed-log-files-without-extracting

于 2016-02-25T04:40:02.043 回答