Bash

根據與單獨文件內容匹配的目前文件名更改文件名

  • October 18, 2020

在一個目錄中,我有幾個 PNG 和一個文本文件。PNG 以 UPC 條碼命名,如052100029962.png,052100045535.png等,我有一個文本文件upcs.txt,其中每一行包含與產品名稱合併的 UPC 程式碼,如下所示:

...
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我什至嘗試在呼叫循環之前放置第二個if循環。

最後,我知道即使公式正確,上述循環也不會保留.png副檔名。為了解決這個問題,我準備手動選擇結果並添加.png.

我究竟做錯了什麼?任何人都可以幫助我更好地理解邏輯嗎?

對於每行包含兩個欄位的文件,您必須使用分隔符。此處 ased插入此分隔符,結果逐行給出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。當然我假設你的第一個欄位總是一個數字序列,第二個欄位沒有空格,不以數字開頭,等等。

如果您需要任何其他操作,例如檢查重複的目標名稱,您可以首先在文件上執行。或者,如果您需要,在任何情況下mv都不要覆蓋現有目標,請使用-n( --no-clobber),同樣-i( --interactive) 也會出於同樣的原因提示使用者輸入。

引用自:https://unix.stackexchange.com/questions/614993