末尾の行を生成せずに「grep -a」する方法は?

末尾の行を生成せずに「grep -a」する方法は?

私はzgreptarballファイルから文字列を取得するために使用します。一般的な方法で行うと、次のような結果が得られます。

aaa.tar.gz内のzgrep

Binary file (standard input) matches

だから私はそのオプションを使って-a(バイナリファイルをテキストのように扱い)、ファイルを読みましたが、結果の前に2/3行の迷惑行を追加しました!

aaa.tar.gzのzgrep -a

aaa.txt        0000777 0000000 0000000 00000000017 13507572577 011066  0 ustar   root     
root
insideinsidebbb  

どのように効果的に削除できますか?

答え1

GNUを使用すると、tarこの--to-commandオプションを使用して各アーカイブメンバーにパイプすることgrepができます(GNUgrepとその--labelオプションを使用して)、一致を含む埋め込みファイルの名前も取得できます。

$ tar --to-command='grep -aH --label="$TAR_ARCHIVE[$TAR_FILENAME]" inside || true' -xf awk.tar.gz
awk.tar.gz[ytab.c]:                             SYNTAX("next is illegal inside a function");
awk.tar.gz[ytab.c]:                             SYNTAX("nextfile is illegal inside a function");
awk.tar.gz[awkgram.y]:                          SYNTAX("next is illegal inside a function");
awk.tar.gz[awkgram.y]:                          SYNTAX("nextfile is illegal inside a function");
awk.tar.gz[lex.c]:/* BUG: this ought to be inside the if; in theory could fault (daniel barrett) */
awk.tar.gz[ytabc.bak]:                          SYNTAX("next is illegal inside a function");
awk.tar.gz[ytabc.bak]:                          SYNTAX("nextfile is illegal inside a function");

これは|| true、アーカイブメンバーに何も見つからないtar: 2631: Child returned status 1場合に警告を防ぐためです。grep

targrep次のヘルパー関数またはスクリプトを作成できます。

#! /bin/sh -
export PATTERN="${1?}"
shift
for file do
  tar --to-command='
    grep -aPH --label="$TAR_ARCHIVE[$TAR_FILENAME]" -e "$PATTERN" || true
  ' -xf "$file"
done

次のように使用されます。

targrep inside *.tar.*

これは、GNUがサポートする最も完全な機能を備えた正規表現であるPCREを使用するため、tar大文字と小文字を区別しない一致を実行できます。たとえば、次のようになります。

targrep '(?i)inside' *.tar.*

(オプションをサポートするためにスクリプトでより複雑なオプションの解析を避ける-i

答え2

あなたが得るゴミはTARヘッダーです。なぜなら、あなたのtarballはTARアーカイブに包まれ、GZIPを使用して圧縮されたファイルであるからです。

圧縮パッケージをgrepする最良の方法は次のとおりです。

tar -xzOf aaa.tar.gz | grep inside
  • x:スタイリッシュ
  • z:アーカイブはGZIP圧縮を使用します。
  • O:stdoutへの出力(GNUtarまたはlibarchiveの仮定bsdtar
  • f:抽出するアーカイブ

tarの出力はすでにプレーンテキストなので(テキストファイルのみを含むと仮定)、grepに "-a"オプションは必要ありません。

答え3

1つの方法は、grepingの前にNUL文字(通常はバイナリファイルの文字列を区切る)を改行文字に変換することです。これはtarあなたの場合には機能しますが、他の種類のバイナリでも機能する可能性があります。

file=xxx.tar.gz

zcat -f < "$file" | tr '\0' '\n' | grep -a inside

関連情報