ディレクトリには複数のPNGとテキストファイルがあります。 PNG名は、などのUPCバーコードにちなんで指定されます。052100029962.png
各行には、次のように製品名とマージされたUPCコードを含む052100045535.png
テキストファイルがあります。upcs.txt
...
052100029962mccormickpepper
052100045535mccormickonesheet
...
*.png*
テキストファイルの文字列と一致する現在のファイル名を使用して、UPC番号なしで各ファイルの名前を製品名に変更したいと思います。052100029962.png
だからmccormickkeeper.png
。以下のさまざまな方法を試しましたが、成功しませんでした。
for f in $(find . -iname "*.png"); do
while read -r line; do
if [[ "$f" == *"$line"* ]]; then ## also tried =~
cp "$f" "$line";
fi
done < upcs.txt
done
「多様性」とは、作業の順序を変えることです。たとえば、ループwhile
の前にループを入れたり、for
製品名のみを含む別のテキストファイルを作成してread
比較したりできます。後者の場合、以下を行いました。
for f in $(find . -iname "*.png"); do
while read -r line; do
if [[ "$f" == *"$line"* ]]; do
while read -r line2; do
cp "$f" "$line2";
done < upcs_names_only.txt;
fi;
done < upcs.txt;
done
while
ループを呼び出す前に、2番目のループを配置してみましたif
。
最後に、公式が正確であっても、上記のループはいいえ.png
拡張子を維持してください。この問題を解決するには、手動で結果を選択します.png
。
私は何が間違っていましたか?誰でもロジックをよりよく理解するのに役立ちますか?
ベストアンサー1
1行に2つのフィールドがあるファイルの場合は、区切り文字を使用する必要があります。ここにsed
この区切り記号を挿入すると、結果が1行ずつ提供されます。mv
#!/bin/bash
while read -r oldname newname; do
[ -f "${oldname}.png" ] && echo mv -- "${oldname}.png" "${newname}.png"
done < <(sed 's/^[0-9]*/& /' upcs.txt)
echo
テスト後に削除してください。もちろん、最初のフィールドは常に一連の数字であり、2番目のフィールドにはスペースがなく、数字で始まらないとします。
重複先の名前解決などの追加操作が必要な場合は、まずファイルでこれを実行できます。または、いずれの場合でも既存の宛先を上書きしたくない場合()をmv
使用すると、同じ理由でユーザーに入力するように求められます。-n
--no-clobber
-i
--interactive