Linux

更改名稱時 mv 會做什麼?

  • June 13, 2020

我有一個非常特殊的問題,在Rename multiples files using Bash scripting中回答我試圖重命名一些文件。這是我正在使用的程式碼

#!/bin/bash
for file in *.HHZ_00; do mv $file ${file/${file:14:2}/00}; done

我所理解的是將字元索引 14(從零開始)後面的 2 個字元替換為 00。

我正在使用 2 個文件子集來測試它,一個是這個

2018113154211.25.AGCC.HHZ_00
2018113154211.25.APAC.HHZ_00

執行程式碼時,這些成功重命名為

2018113154211.00.AGCC.HHZ_00
2018113154211.00.APAC.HHZ_00

第二個子集在此失敗,這個子集是

2018070220829.28.AGCC.HHZ_00
2018070220829.29.APAC.HHZ_00

這些重命名不成功

2018070220829.00.AGCC.HHZ_00
2018070220800.29.APAC.HHZ_00

請注意第二個文件的索引 11 和 12 是如何更改的,而不是我想要的 14 和 15,現在非常奇怪的是,我第二次執行它,使用最後一個文件作為輸入,我得到了

2018070220829.00.AGCC.HHZ_00
2018070220800.00.APAC.HHZ_00

這部分成功,但現在第二個文件名被破壞了……我做錯了什麼?是因為 29 在這些文件中重複嗎?

如果有人使用 rename 命令的解決方案也很棒,我嘗試使用它,但我不熟悉語法。

是的,因為字元重複;${file/${file:14:2}/00}替換出現在位置 14-15 的任何字元的第一個實例。

在 bash 中執行此操作而無需嵌套參數擴展的一種簡單方法是

$ for file in *.HHZ_00; do 
   echo mv "$file" "${file:0:14}00${file:16}"
 done
mv 2018070220829.28.AGCC.HHZ_00 2018070220829.00.AGCC.HHZ_00
mv 2018070220829.29.APAC.HHZ_00 2018070220829.00.APAC.HHZ_00
mv 2018113154211.25.AGCC.HHZ_00 2018113154211.00.AGCC.HHZ_00
mv 2018113154211.25.APAC.HHZ_00 2018113154211.00.APAC.HHZ_00

POSIXly,您可以使用%%and #(兩次)分別刪除最長的後綴和最短的前綴:

$ for file in *.HHZ_00; do 
   pfx="${file%%.*}"; rem="${file#*.}"; sfx="${rem#*.}" 
   echo mv "$file" "${pfx}.00.${sfx}"
 done
mv 2018070220829.28.AGCC.HHZ_00 2018070220829.00.AGCC.HHZ_00
mv 2018070220829.29.APAC.HHZ_00 2018070220829.00.APAC.HHZ_00
mv 2018113154211.25.AGCC.HHZ_00 2018113154211.00.AGCC.HHZ_00
mv 2018113154211.25.APAC.HHZ_00 2018113154211.00.APAC.HHZ_00

echo一旦您對它正在做正確的事情感到滿意,請刪除它。

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