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 $ FILE

4

7 に答える 7

13

アーカイブを一度だけ処理するこの単純なソリューションを誰も投稿していないようです。

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

ここでtarは、各ファイルの名前を変数に渡し(docsgrepを参照)、一致ごとに出力するために使用されます。また、一致しないファイルの抽出に失敗しても文句を言わない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

|1つの条件:ファイル名に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

これは信じられないほどハックですが、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 に答える