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
-0
null で終わるパラメータを読み取るための非標準オプションをサポートする場合。
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 4
。xargs
xargs
-P