Shell-Script
通過反轉編號順序重命名文件
我有很多文件被命名為:
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
預先存在的後綴命名的文件,而不是後一種方法(儘管-i
會mv
在此之前提示您)。或者,-renamed
您可以將重命名的文件移動到renamed
目錄中,而不是添加後綴。