
私はzgrep
tarballファイルから文字列を取得するために使用します。一般的な方法で行うと、次のような結果が得られます。
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