gzipで圧縮されたtar-ballcompressedArchive.tgz(+ 100ファイル、+ 5GBの合計)があるとしましょう。
指定されたファイル名パターン(たとえば、プレフィックス* .jpg)に一致するすべてのエントリを削除し、残りをgzip:ed tar-ballに保存する最も簡単な方法は何ですか?
古いアーカイブを置き換えたり、新しいアーカイブを作成したりするのが最も速いことは重要ではありません。
答え1
GNUを使用すると、tar
次のことができます。
pigz -d < file.tgz |
tar --delete --wildcards -f - '*/prefix*.jpg' |
pigz > newfile.tgz
そしてbsdtar
:
pigz -d < file.tgz |
bsdtar -cf - --exclude='*/prefix*.jpg' @- |
pigz > newfile.tgz
(pigz
マルチスレッドバージョンですgzip
)。
次のようにファイル自体を上書きできます。
{ pigz -d < file.tgz |
tar --delete --wildcards -f - '*/prefix*.jpg' |
pigz &&
perl -e 'truncate STDOUT, tell STDOUT'
} 1<> file.tgz
しかし、これは非常に危険です。特に、結果が元のファイルよりも圧縮されていない場合(この場合、2番目のファイルは最初のファイルがまだpigz
読み取られていないファイル領域を上書きする可能性があります)。
答え2
単純なアプローチを過小評価しないでください。あなたの目的に合わせて十分速いかもしれません。そしてAVFSアーカイブにディレクトリとしてアクセスします。
cd ~/.avfs/path/to/original.tar.gz\#
pax -w -s '/^.*\.jpg$//' | gzip >/path/to/filtered.tar.gz # POSIX
tar -czf /path/to/filtered.tar.gz -s '/^.*\.jpg$//' . # BSD
tar -czf /path/to/filtered.tar.gz --transform '/^.*\.jpg$//' . # GNU
より原始的なツールを使用して、最初に除外されたファイルからファイルを抽出し、.jpg
新しいアーカイブを作成します。
mkdir tmpdir && cd tmpdir
<original.tar.gz gzip -d | pax -r -pe -s '/^.*\.jpg$//'
pax -w . | gzip >filtered.tar.gz
cd .. && rm -rf tmpdir
タールに以下がある場合--exclude
:
mkdir tmpdir && cd tmpdir
tar -xzf original.tar.gz --exclude='*.jpg'
tar -czf filtered.tar.gz .
cd .. && rm -rf tmpdir
ただし、rootとして実行しないと、ファイルの所有権とスキーマが破損する可能性があります。最良の結果を得るには、高速ファイルシステムの一時ディレクトリであるtmpfsを使用してください(ファイルシステムが十分に大きい場合)。
パススルー(アーカイブファイルの読み取りやアーカイブファイルの書き込み)として機能するアーカイバのサポートは制限される傾向があります。GNU tarはアーカイブからメンバーを削除できます。そして--delete
ジョブオプション(「このオプションは、からのフィルタとして機能すると正しく機能することが報告されています--delete
。」)これが最良の選択肢かもしれません。tar
stdin
stdout
数行のPythonコードで強力なアーカイブフィルタを作成できます。それtarfile
ライブラリは検索できないストリームから読み書きでき、Pythonで任意のコードを使用してフィルタリング、名前変更、変更などを実行できます。
#!/usr/bin/python
import re, sys, tarfile
source = tarfile.open(fileobj=sys.stdin, mode='r|*')
dest = tarfile.open(fileobj=sys.stdout, mode='w|gz')
for member in source:
if not (member.isreg() and re.match(r'.*\.jpg\Z', member.name)):
sys.stderr.write(member.name + '\n')
dest.addfile(member, source.extractfile(member))
dest.close()
答え3
Mac OSXでtarを使用すると、次のことができます。
tar -czf b.tgz --exclude '*.jpg' @a.tgz
mv b.tgz a.tgz
答え4
私は使用する:
tar -xvf myLarge.gz --exclude "prefix" | tar -czvf myLarge.gz -T -
これは次のことを行います。
- 「を含むファイルを除くすべてのファイルを抽出します。プレフィックス」
- (
-T -
)残りの内容をtarにパイプし、myLarge.gzを再圧縮します。