web-dev-qa-db-ja.com

tbzファイルへのファイルの追加

何千もの.tbzアーカイブファイルを更新する方法を探しているので、シェルスクリプトを使用してこれを実行します。それぞれに1つのファイルを追加する必要があります。

私の質問は、各tbzのコンテンツを抽出せずにこれを実行し、含まれているtarに含まれている新しいファイルで再圧縮するより速い方法はありますか?コマンドはどのようになりますか?

ありがとう

8
BottleZero

tarは既存のアーカイブにファイルを追加できますが、圧縮することはできません。標準のtarballを残して、圧縮されたアーカイブをbunzip2する必要があります。次に、tarの機能を使用して既存のアーカイブにファイルを追加し、bzip2で再圧縮できます。

マニュアルから:

 -r      Like -c, but new entries are appended to the archive.  Note that this only
         works on uncompressed archives stored in regular files.  The -f option is
         required.
12
DopeGhoti

他の答え 正解:圧縮されたtarアーカイブを解凍せずに適切に更新することはできません。 GNU tarドキュメント はそれを示唆しており、更新しようとすると明示的なエラーメッセージが表示されて失敗します:

$ tar --concatenate --file=cat.tar.bz2 two.tar.bz2 
tar: Cannot update compressed archives
tar: Error is not recoverable: exiting now

ただし、解凍を必要としない汚い種類のソリューションに興味がある場合は、次の観察に基づいて提供できます。 :

  • catを使用したbzip2ストリームの追加がサポートされており、有効なbzip2ストリームが生成されます(gzipについても同じことが言えます)。
  • catを使用してtarを追加すると、有効なtarファイルが生成されないため、--concatenateオプションが存在しますが、tarに有効なふりをするように依頼できます。

--concatenate操作を使用する代わりに、catを使用して2つのアーカイブを連結したい、または使用しようとする方が直感的に思えるかもしれません。結局のところ、catはファイルを結合するためのユーティリティです。

ただし、tarアーカイブにはファイルの終わりマーカーが組み込まれており、連結されたアーカイブを1つのアーカイブとして正しく読み取るには、このマーカーを削除する必要があります。 --concatenateは、新しいアーカイブが追加される前に、ターゲットアーカイブからアーカイブ終了マーカーを削除します。 catを使用してアーカイブを結合すると、結果は有効なtar形式のアーカイブにはなりません。 catユーティリティの使用に追加されたアーカイブからファイルを取得する必要がある場合は、--ignore-zeros-i)オプションを使用します。

この知識に基づいて、次のことができます。

cat {one,two}.tar.bz2 >combined.tar.bz2

これにより、上記のドキュメントスニペットで説明されているように、無効なtarファイルになりますが、--ignore-zerosを使用すると、完全に読み取ることができます。

## Show contents of `one.tar.bz2'
$ tar tf one.tar.bz2
a
b

## Show contents of `two.tar.bz2'
$ tar tf two.tar.bz2
c

## Show contents of `combined.tar.bz2', bypassing the bad format
$ tar tif combined.tar.bz2
a
b
c

上記が元の2つのアーカイブからの3つのファイルすべてをリストしているのに対し、-iを(正しく)省略すると、最初の元のアーカイブからのファイルのみがリストされることに注意してください。

$ tar tf combined.tar.bz2 
a
b

繰り返しになりますが、これは汚いトリックにすぎませんが、書き込み側と読み取り側の両方を制御し、この方法で作成されたファイルから読み取ろうとするときに-iが使用されることを確認できると便利です。

10
dhag