1つのコマンドを使用して複数のtarファイルを個別に解凍するには?

1つのコマンドを使用して複数のtarファイルを個別に解凍するには?

aa.tar、bb.tar、cc.tar、...などのtarファイルがたくさんあります。

aa/、bb/、cc/...などの独自のディレクトリに抽出したいと思います。

私はこれを試しました:

ls | xargs -n1 -I {} tar -xvf {} -C `basename {} .tar`

これはうまくいきません。 {}は完全なtarファイル名として使用するか.tar、 。

どのように動作させることができますか?

答え1

実行時{}にコマンドの置換(呼び出し)には使用できません。basename今後電話もしxargsました。これは、ディレクトリを各アーカイブに対してtar(文字通り)名前付きディレクトリに変更しようとすることを意味します。{}

forたとえば、ループを使用する必要はありませんxargs

for t in *.tar ; do
  bn="$(basename "$t" .tar)"
  mkdir -p "$bn"
  tar -xvf "$t" -C "$bn"
done

また見なさい:なぜいいえ解析ls(および実行方法)?

答え2

命令が機能しない理由は、命令の置き換え(バックティックで書かれたビット)がxargs開始前に一度実行されるためです。

としてタグ付けされたので、に基づいてソリューションをxargs提供すると思いました。xargs

まず、単一のアーカイブを解凍するには、tar次のものを使用できます。

dir=${archive%.tar}
mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"

...$archiveアーカイブのファイル名が含まれており、tarアーカイブが一般(圧縮されていない)であるとします。

明らかにこれを繰り返すことができます

for archive in *.tar; do
    dir=${archive%.tar}
    mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"
done

xargsただし、これにより、複数のコマンドを並列に実行するなど、いくつかの一般的な(非標準ですが)機能を使用できなくなります。

初期コマンドを一度に4つずつ実行するには、tarアーカイブ名をxargs標準入力に入力する必要があります。

私たちはできます

printf '%s\n' *.tar | xargs ...

これは明らかに、アーカイブ名に新しい行が含まれていないと想定していますが、次のようにしてこの問題を解決できます。

printf '%s\0' *.tar | xargs -0 ...

実装がxargs-0null で終わるパラメータを読み取るための非標準オプションをサポートする場合。

fromから解凍を実行するxargs最も簡単な方法は、サブシェルで実行することですsh -c

printf '%s\0' *.tar |
xargs -0 -P 4 -I {} sh -c 'dir=${1%.tar}; mkdir -- "$dir" && tar -x -f "$1" -C "$dir"' sh {}

sh -cシェルスクリプトは$1初期コマンドと同じで、$archiveスクリプトは各アーカイブに対して一度実行されます。実装がサポートしている場合、オプションは4つの抽出オプションを並列に実行します-P 4xargsxargs-P

関連情報