2011-08-08 20 views
3

ディレクトリ内の.tar.gzファイルのリストを展開する際に問題が発生しました。私のディレクトリで同じパッケージの束を同じフォルダの中で解凍するにはどうしたらいいですか?

result.tar.gzがたくさんある、彼らは同じ名前です、彼らは

result.tar.gz 
result (1).tar.gz 
result (2).tar.gz 
result (3).tar.gz 
result (4).tar.gz 
.... 
.... 
.... 
.... 

...と改称され、私は、それらのすべてをuntarしたいです1つのlinuxコマンド。 ので、私は

tar zxvf * 

または

tar zxvf result*.tar.gz 

の両方を使用しようとするが、同時にすべてのパッケージをuntarする方法を知っている誰がこのエラーに

tar: result (3).tar.gz: Not found in archive 
tar: result (4).tar.gz: Not found in archive 
tar: result (5).tar.gz: Not found in archive 
tar: result (6).tar.gz: Not found in archive 

を得ましたか。

答えて

5

tarは一つだけを処理する方法を知っています。tarファイル:一度にfで指定されたファイル。コマンドラインで追加の名前を指定すると、指定された.tarファイルから抽出するファイルとして解釈されます。

これまでの回答のほとんどは、スペースや改行などの特殊文字を含む通常とは異なるファイル名を扱っていません。

正しい答えはこれです:

for file in *.tar.gz ; do 
    tar xzf "$file" 
fi 

他の許容可能な答えがfind

find . -maxdepth 1 -type f -name '*.tar.gz' -exec tar xzf {} \;` 

なぜできない私...

  • 使用ls *.tar.gz | ...を使用することです?

    lsはファイル名の特定の文字を壊してしまいます(つまり、安全ではありません)。このためにlsを使用する必要がある場合は、ls -1を使用するよう注意してください。改行と改行のみをレコードセパレータとして扱うように注意してください。これはまだ安全ではありませんが、より安全です。

  • $fileを引用符なしで使用しますか?

    名前にスペースが含まれているファイルは、とりわけあなたが期待していない方法で解釈されるためです。例:monthly backup.tar.gzというファイルはtar xzf monthly backup.tar.gzと解釈され、monthlyというアーカイブが存在しないため、エラーが発生します。

  • echo | xargs tarを使用しますか?

    echoはファイル名、特に名前にスペースを含むファイル名をマングルするためです。

エスケープシーケンスとして解釈されることからの入力でバックスラッシュを防ぐことができますあなたはほとんど常にread -rを使用したいwhile readループを実行します。 foo\barという名前のファイルがある場合は、readなしで、-rを正しく読み取れません。

EDIT:コメントパー

が、ここではサブディレクトリにtarballを抽出する方法です。

for file in *.tar.gz ; do 
    # strip any leading path information from the file name 
    name_only="${file##*/}" 

    # strip the extension .tar.gz 
    without_extension="${name_only%.tar.gz}" 

    # make a directory named after the tar file, minus extension 
    mkdir -p "$without_extension" 

    # extract the file into its own directory 
    tar xzf "$file" -C "$without_extension" 
done 

上記のうち、Iはtarballの名前を付けたディレクトリに抽出します。ただし、一意のディレクトリ名を作成するためのスキームで十分です。たとえば、番号の付いたディレクトリを抽出するバージョンを次に示します。

let n=0 
for file in *.tar.gz ; do 
    mkdir -p "$n"; 
    tar xzf "$file" -C "$n" 

    let n=n+1 
done 
+0

良い答えですが、フォローアップの質問は、すべてのtar.gzが同じファイル名を持つようになりました。すべてを解凍すると、新しいファイルは古いファイルを上書きします。ファイル名を自動的に変更することで、どうやったら避けることができますか? –

+0

@Kit Ho:これは、スクリプトごとに新しいサブディレクトリを作成する少し複雑なスクリプトを必要とします。私は答えを更新して、それを行う方法のサンプルを含めます。 – Sorpigal

+0

非常に詳細な答え!ありがとう –

1

パイピングを試しましたか?

このような何かが動作するはず:

ls *.tar.gz | while read line; do tar -xzvf "${line}"; done

EDIT:それは抽出時に

また、tarはファイルを上書きします。これを回避するには、(manページから)次のいずれかを試してみてください。

-k, --keep-old-files 
     keep existing files; don't overwrite them from archive 

--keep-newer-files 
     do not overwrite files which are newer than the archive 

EDIT: 空白のエラーを回避する "$ライン"

+0

これは機能しません。同じエラー... –

+0

私のローカルでこれをテストしましたが、動作していないようです。編集:on Mac OS X、btw。 – ace

+0

申し訳ありません、読んでいる間に追加されました。これは今ではうまくいくはずです – tjameson

2

別の解決策、Google検索を介してこれを見つけました。 | link

for i in *.tar.gz; do tar -xvzf "$i"; done 
+1

しかし、それは十分に難読化されていません;)私はコマンドを一緒につなげることができるので、配管が好きです。 – tjameson

+0

私も配管が好きです。ちょうどbashで何か違うものを提供しています。 :) +1ところで。 – ace

+0

後で。 Forループにも余裕があります... – tjameson

1

あなたは* .tar.gzのこの

エコーのような何かをする必要があり

1

-zxvf xargsの-n 1つのタール、あなたの答えを選ぶ前に、あなたはそれのようなファイル名で正しく扱うことを確認することをお勧めします:

あなたはGNUパラレルがインストールされている場合
My brother's 12" records.tar.gz 

ls result*.tar.gz | parallel tar zxvf 

あなたはパイプなし希望する場合:

parallel tar zxvf ::: result*.tar.gz 

私は、多くの場合、展開したファイルが私であることを確認したいですnは、独自のdirが、そう:

ls result*.tar.gz | parallel mkdir {.}\;cd {.}\;tar zxvf ../{} 

か:

parallel "mkdir {.};cd {.};tar zxvf ../{}" ::: result*.tar.gz 

より多くを学ぶためにイントロビデオを見る:http://www.youtube.com/watch?v=OpaiGYxkSuQ

関連する問題