77

ディレクトリにたくさんのtarファイルがあり、それらからすべてのファイルを一度に抽出したいと考えています。しかし、これは何もしないようです:

$ tar xf *.tar

何が起きてる?大量のファイルを一度に untar するにはどうすればよいですか?

4

3 に答える 3

150

何が起きてる?

当初、このtarコマンドは磁気テープ デバイスで使用することを目的としていました。一度に 1 つのデバイスでしか実行できないためtar、構文は 1 つのデバイスのみを想定して設計されています。渡された最初のファイルまたはディレクトリは、問題のアーカイブと、アーカイブの内容が操作に含まれるその他のファイルまたはディレクトリを保持するデバイスであると想定されていました。したがって、tar抽出 (xオプション) の場合、最初に渡されたファイルがアーカイブになり、他のすべてのファイルが抽出されるファイルになります。したがって、2 つの*.tarファイル (たとえばa.tarb.tar) がある場合、コマンドは次のように展開されます。

$ tar xf a.tar b.tar

a.tarという名前のファイルが含まれていない限りb.tartarコマンドは何も実行せず、静かに終了します。厄介なことに、Solaris バージョンのtarは、リターン コードまたは冗長オプション ( v) で問題を報告しません。一方、冗長オプションをオフにしても、GNU tar返品2とスパムは次のようになります。STDERR

tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors

大量のファイルを一度に untar するにはどうすればよいですか?

複数のアーカイブ ファイルを入力として受け入れるには書き直すのが遅すぎtarますが、制限を回避するのはそれほど難しくありません。

ほとんどの人にとってtar、複数のアーカイブに対して複数回実行することが最も適切なオプションです。ファイル名を 1 つだけ渡すtar xfと、予想どおり、アーカイブされたすべてのファイルが抽出されます。1 つのアプローチは、シェルforループを使用することです。

$ for f in *.tar; do tar xf "$f"; done

別の方法は、次を使用することxargsです。

$ ls *.tar | xargs -i tar xf {}

または、多数の代替tarファイル リーダーの 1 つを使用することもできます。最後に、真に献身的なプログラマーはtar、希望どおりに動作する置換を簡単に作成できます。形式は簡単で、多くのプログラミング言語には、ファイルを読み取るためのライブラリがありますtar。たとえば、Perl プログラマーの場合は、Archive::Tarモジュールを見てください。

警告

やみくもに大量のファイルを untar すると、予期しない問題が発生する可能性があります。最も明白なのは、特定のファイル名が複数のtarファイルに含まれている可能性があることです。tarはデフォルトでファイルを上書きするため、最終的に得られるファイルの正確なバージョンは、アーカイブが処理される順序によって異なります。さらに厄介なことに、この「巧妙な」最適化を試みると、ファイルのコピーが破損する可能性があります。

for f in *.tar; do
  tar xf "$f" &
done
wait

と の両方a.tarb.tar同じファイルが含まれていて、同時に抽出しようとすると、結果は予測できません。

関連する問題として、特に信頼できないソースからアーカイブを取得する場合に、tarbombが発生する可能性があります。

部分的な解決策の 1 つは、展開先の新しいディレクトリを自動的に作成することです。

for f in *.tar; do 
  d=`basename "$f" .tar`
  mkdir "$d"
  (cd "$d" && tar xf "../$f")
done

これは、ファイルが絶対パスでアーカイブに指定されている場合には役に立ちません (通常、これは悪意のある兆候です)。その種のチェックを追加することは、読者の演習として残されています。

于 2009-02-24T22:23:58.483 に答える
12

すべての tar ファイルが同じフォルダーにある場合は、tcsh シェルでこれを行います。常に動作します。

find -iname \*.tar -exec tar -xvf {} \;

これは上記の回答と同じですが、もう少し簡潔だと思います。

于 2015-12-31T21:37:09.013 に答える
8
find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \;
于 2014-06-12T15:08:10.153 に答える