Bash

如何通過組合三個變數並忽略文件副檔名來批量重命名文件?

  • May 20, 2022

我正在嘗試創建一個重命名一組文件的腳本。通常它們將是 TIF,但有時可能會偶爾出現奇怪的問題,所以我想重命名文件並忽略文件副檔名。

文件名將全部相同,中間拋出的紀元時間作為區分符。最終結果將與此類似:

Name1=CLMSFILE

Name2=Epoch

Name3=_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES

CLMSFILE53253_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES.TIF (or other extension)

這是我目前擁有的

#Rename files and insert epoch time
name1=$CLMSFILE
name2=$(date  +%s%3N)
name3=$_A\ BUNCH\ OF\ OTHERTEXT_WITH_A_MIXTURE\ OF\ UNDERSCORES\ AND_SPACES

for f in *; do
 newname=$name1$name2$name3
 mv -n "$f" "${newname}"
done

執行此之後,我只重命名了第一個文件,但它忽略了第一個變數並且沒有副檔名。

1653049404956 _A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES
220220217SOMEORG20003_01.TIF
220220217SOMEORG30004_01.TIF

您的 shell 腳本中有幾個問題會導致您觀察到錯誤:

  1. 你說第一個名字部分是CLSMFILE。但是,在您聲明的變數分配中,您將名為 的shell 變數name1=$CLMSFILE的內容分配給第一部分,該變數可能不存在,因此為空。這部分實際上也是如此,但是您碰巧以 , 開頭的字元串,並且在 shell 中具有特殊含義,因此解釋在 之後立即停止,並且字元串的其餘部分未更改地導入到您的變數中。CLSMFILEname3``_``$_``_
  2. 您的腳本會嘗試將所有文件重命名為相同的名稱。幸運的是,您使用了該-n選項,否則您將失去目錄中除最後一個文件之外的所有文件。

原因是date命令 inname2=$(date ...)在賦值時進行評估,而不是每次使用$name2變數時。所以它對於循環的所有迭代都是恆定的。 3. 您聲明您想要一個文件副檔名,但您忘記為文件添加副檔名。mv重命名整個 filename,而不僅僅是 之前的部分,僅僅是因為文件名中允許有.多個。.

我建議您使用shellcheck,也可作為獨立工具使用,以擷取 shell 腳本中的錯誤。

以下修改應該有效:

name1="CLMSFILE"
name3="_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES"

for f in *; do
 basename=${f%.*}
 newbasename="$name1$(date  +%s%3N)$name3"
 newname=${f/$basename/$newbasename}
 mv -n "$f" "${newname}"
done

這使用 shell 字元串操作來

  • 將 的“基本名稱”部分$f,即直到最後一個.分隔部分的所有內容,儲存在一個變數中$basename
  • 根據您的規則生成新的基本名稱,但在date每次循環迭代時執行該命令
  • $basename子字元串$f替換為$newbasename
  • 相應地重命名文件

理想情況下,你會用類似的mv -n ...東西替換零件

echo "Renaming '$f' to '$newname'"

直到您確定名稱生成邏輯正常工作。

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