並列化したいbash抽出機能があります。その使命は、入れ子になったアーカイブを見つけて抽出することです。理想的には、if評価とすべての対応するタスクをバックグラウンドで送信したいと思います。問題は、if評価の作業項目を順番に完了する必要があるため、「&」だけを追加できないことです。 ifのコマンドに。完全なif評価を単一のバックグラウンドジョブにカプセル化し、コマンドが順次実行されるようにする方法はありますか?
現在動作している機能は次のとおりです。
extract () {
IFS=$'\n'
trap exit SIGINT SIGTERM
for ext in zip rar tar.gz tar.bz2 tbz tgz 7z tar; do
while [ "`find . -type f -iname "*.$ext" | wc -l`" -gt 0 ]; do
for z in `find . -type f -iname "*.$ext"`; do
if [ ! -d "`echo "$z" | rev | cut -c$(expr ${#ext} + 2)- | rev`" ]; then
echo "Extracting `basename "$z"` ..."
mkdir -p `echo "$z" | rev | cut -c$(expr ${#ext} + 2)- | rev`
if [[ "$z" =~ ^.*\.7z$ ]]; then 7z x "$z" -o"`echo "$z" | rev | cut -c$(expr ${#ext} + 2)- | rev`" > /dev/null
elif [[ "$z" =~ ^.*\.zip$ ]]; then unzip -uoLq "$z" -d `echo "$z" | rev | cut -c$(expr ${#ext} + 2)- | rev` 2>&1 | grep -ive warning
elif [[ "$z" =~ ^.*\.tar\.xz$ ]] || [[ "$z" =~ ^.*\.tar\.gz$ ]] || [[ "$z" =~ ^.*\.tar\.bz2$ ]] || [[ "$z" =~ ^.*\.tgz$ ]] || [[ "$z" =~ ^.*\.tbz$ ]] || [[ "$z" =~ ^.*\.tar$ ]] ; then tar -xaf "$z" -C `echo "$z" | rev | cut -c$(expr ${#ext} + 2)- | rev`
elif [[ "$z" =~ ^.*\.rar$ ]]; then unrar x -y -o+ "$z" `echo "$z" | rev | cut -c$(expr ${#ext} + 2)- | rev`
fi
rm -f "$z"
else echo "Omitting `basename "$z"`, directory with that name already exists."; rm -f "$z"
fi
done
done
done
}
そして、ソースアーカイブを削除せずに抽出を実行する方法があるかどうか疑問に思います。現時点では、無限ループを防ぐためにこれを行います。現時点では、この機能は十分に安定しているため、データが失われることはありません。しかし、安全のために何も削除しないことをお勧めします。
ベストアンサー1
同じfindコマンドを複数回実行するのはなぜですか?二重各拡張ごとに?ディレクトリツリーを1回だけ移動するfindコマンドを生成できます。
EXT_REGEX='.*(zip|rar|tar.gz|tar.bz2|tbz|tgz|7z|tar)$'
find . -regextype posix-egrep -iregex $EXT_REGEX
これで、ネストされたループはまったく必要なく、while
無限ループの問題を引き起こすネストされたループも必ずしも必要ではありません。
次に、ファイル名にスペースが含まれているとコードが破損します。追加すると、この問題を解決できます。
IFS=''
(for z in ...
空間内の出力分割を停止します。)
最後に、&
各分岐の末尾に1つを追加すると、if/elif
並列に実行されます。
ところで、echo "$z" | rev
これらすべてが何を達成することになっていますか?何とか複数行のファイル名を取得していますか?