web-dev-qa-db-ja.com

含まれているファイル名に基づいてバッチZip名前変更ファイル

15000のZipファイルを含むディレクトリがあります。解凍すると、次の形式のファイルを含むすべてのファイルの名前を変更したい

YYYYMMDD_IPC.csv

YYYYMMDDはたまたま日付ですが、この問題の目的のために正確に8桁の文字列です。次に、Zipファイル自体の名前を変更する必要があります

YYYYMMDD_IPC.Zip.

次のコマンドラインまで取得しましたが、Zipファイルの名前を変更するために使用するファイルからYYYYMMDDをキャプチャする方法がわかりません。

find . -iname '*.Zip' | while read file; do unzip -l "$file" | grep -q -P '\d{8}_IPC.csv' && echo $file; done 2>&- 

読んでくれてありがとう。

2
user2926302
_find . -iname '*.Zip' -exec bash -c 'name=$(unzip -qql "$1"  '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1); [ "$name" ] && mv "$1" "${name%csv}Zip"' none {} ';'
_

使い方

このコマンドの形式は次のとおりです。

_find . -iname '*.Zip' -exec bash -c '...' none {} ';'
_

これは、現在のディレクトリとその下のすべてのサブディレクトリで.Zipファイルを検索します。そのようなファイルが見つかるごとに、単一引用符で囲まれたbashコマンドが実行されます。見つかったファイルの名前は、bashコマンドの引数1、_$1_で提供されます。この場合、bashコマンドには2つの部分があります。最初は、csvファイル名を抽出し、bash変数nameに保存します。

_name=$(unzip -qql "$1"  '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1)
_

上記ではcommand substitutionを使用しています。$(...)内のコマンドが実行され、その標準出力がキャプチャされます。この場合、変数nameに割り当てます。コマンド_unzip -qql "$1" '*_IPC.csv'_は、glob _*_IPC.csv_に一致するすべてのファイル名をZipファイルから静かに抽出します。グロブ_*_IPC.csv_に制限する必要はありませんが、Zipファイルに多くのファイルが含まれている場合、これにより速度が向上する可能性があります。

Grepコマンド_rep -oE '[[:digit:]]{8}_IPC.csv'_はさらに、8桁で始まる名前のみを選択します。 _head -n1_コマンドは、最初に見つかったそのような名前を選択します。そのような名前が1つしかない場合、_head -n1_は必要ありません。ただし、headを保持すると、最初の一致後にパイプラインが終了するため、速度が向上する可能性があります。

2番目の部分では、空でないnameの取得に成功したことをテストし、もしそうであれば、Zipファイルの名前を変更します。

_[ "$name" ] && mv "$1" "${name%csv}Zip"
_

上記ではsuffix Removalを使用してcsvファイル名をZipファイル名に変更します。 _${name%csv}_は、サフィックスcsvを削除した後、_$name_を返します。 _${name%csv}Zip_はZipサフィックスを追加します。

4
John1024