Shell-Script

通過反轉編號順序重命名文件

  • December 22, 2019

我有很多文件被命名為:

data1_1.txt
data1_2.txt
data1_3.txt
data2_1.txt
data2_2.txt
...

然而,這些被下載並以相反的順序命名。我怎樣才能批量重命名所有這些,以便結果是:

data1_3.txt
data1_2.txt
data1_1.txt
data2_2.txt
data2_1.txt
...

我的第一個想法只是一個 bash / zsh 腳本,但如果有其他工具可以更好地工作,請告訴我。

zsh

autoload zmv # best in ~/.zshrc

typeset -A c=()
zmv -n '(*)_<->.txt(#qnOn)' '$1_$((++c[${(b)1}])).txt-renamed' &&
 : zmv '(*)-renamed' '$1'

(刪除-n(dry-run) 和:,如果滿意(並記住在c=()沒有空執行的情況下再次執行之前重新初始化))。

  • <->: 就像<1-12>匹配一個範圍內的十進制數字,但這裡沒有指定範圍,因此匹配一個或多個十進制數字的任何序列。也可以寫成[0-9]##where ##iszsh等價於 ERE +
  • (#q...)是指定glob 限定符的顯式語法。
  • n: 按數字排序
  • On: 按名稱反向排序。因此,與n上面一樣,它以數字方式對匹配文件列表進行反向排序。
  • 對於替換,$1包含在 中擷取的內容(*),因此是之前的部分_<digits>.txt
  • 我們追加$((++c[${(b)1}]))$c前面聲明的關聯數組在哪裡。
  • ${(b)1}是帶有 glob 字元的轉義(沒有它,如果包含$1它,它將無法正常工作)。$1``]
  • 我們分兩個階段進行(附加一個-renamed在第二階段剝離的後綴),以避免在此過程中覆蓋文件。

在您的樣本中,這給出了:

mv -- data2_2.txt data2_1.txt-renamed
mv -- data2_1.txt data2_2.txt-renamed
mv -- data1_3.txt data1_1.txt-renamed
mv -- data1_2.txt data1_2.txt-renamed
mv -- data1_1.txt data1_3.txt-renamed

mv -- data1_1.txt-renamed data1_1.txt
mv -- data1_2.txt-renamed data1_2.txt
mv -- data1_3.txt-renamed data1_3.txt
mv -- data2_1.txt-renamed data2_1.txt
mv -- data2_2.txt-renamed data2_2.txt

請注意,從技術上講,它不會顛倒 order,或者僅在數字遞增 1 並從 1 開始的情況下,就像在您的範例中一樣。它將把所有[1, 2, 3], [4, 5, 6],[0, 10, 20]變成[3, 2, 1]

要顛倒列表,它會涉及更多。它可能是這樣的:

all_files=(*_<->.txt(n))
prefixes=(${all_files%_*})

for prefix (${(u)prefixes}) {
 files=(${(M)all_files:#${prefix}_<->.txt})
 new_files=(${(Oa)^files}-renamed)
 for old new (${files:^new_files})
   echo mv -i -- $old $new-renamed
}

echo(高興時刪除)。

zmv '(*)-renamed' '$1'再次作為第二階段執行。

在另一個帶有附加[0, 3, 10, 20]列表的範例中,作為第三個範例,它給出:

mv -i -- data1_1.txt data1_3.txt-renamed
mv -i -- data1_2.txt data1_2.txt-renamed
mv -i -- data1_3.txt data1_1.txt-renamed
mv -i -- data2_1.txt data2_2.txt-renamed
mv -i -- data2_2.txt data2_1.txt-renamed
mv -i -- data3_0.txt data3_20.txt-renamed
mv -i -- data3_3.txt data3_10.txt-renamed
mv -i -- data3_10.txt data3_3.txt-renamed
mv -i -- data3_20.txt data3_0.txt-renamed

這些解決方案不假設文件名可能包含什麼字元(或非字元),不會重命名文件,除非它們以_<digits>.txt. 基於-zmv的方法將防止覆蓋以-renamed預先存在的後綴命名的文件,而不是後一種方法(儘管-imv在此之前提示您)。或者,-renamed您可以將重命名的文件移動到renamed目錄中,而不是添加後綴。

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