
我有以下一組文件
top_axi_256_wrapper_05.02.01.14.00_sample06.tgz
top_axi_128_wrapper_05.02.01.14.00_sample06.tgz
我想用 替換05.02.01.14.00
零件05_02_01_14_00
。所以最終的輸出就是以下重命名的文件
top_axi_256_wrapper_05_02_01_14_00_sample06.tgz
top_axi_128_wrapper_05_02_01_14_00_sample06.tgz
我的目錄也可能包含以下類型的檔案名稱。
a72_a_0.0.0_0.00.04_ac_dc.tgz
在這裡,我想將文件重命名為
a53_1c_256K_a_0_0_0_0_00_04_ac_dc.tgz
這個怎麼做?
答案1
您基本上想用下劃線替換點,除了最後一個點之外。
您可以使用 bash 的參數擴充來實現:
for file in * ; do
replace_all=${file//./_}
newname=${replace_all%_*}.${replace_all##*_}
mv "$file" "$newname"
done
//./_
方法將所有點替換為底線%_*
方法刪除最後一個底線之後的所有內容##*_
方法刪除最後一個底線之前的所有內容
或者您可以先保存擴展名,然後將其刪除,用下劃線替換所有點,然後將擴展名添加回來。留給讀者當作練習。
答案2
perl
基於 -的實用rename
程式可以使用任何perl
語句來重新命名文件,而不僅僅是s///
搜尋和取代運算子或y//
翻譯運算子(只需確保您設定$_
為要將文件重新命名為的任何內容)。
從man rename
:
“rename”根據第一個參數指定的規則重新命名所提供的檔案名稱。 perlexpr 參數是一個 Perl 表達式,預計它會修改
$_
Perl 中至少某些指定檔名的字串。如果給定的檔案名稱未被表達式修改,則不會重新命名。如果命令列上沒有給出檔案名,則將透過標準輸入讀取檔案名。
例如:
rename 'my($b,$e) = m/^(.*)\.([^.]+)$/; $b =~ s/\./_/g; $_="$b.$e"' files
這會將檔案名稱拆分為基本名稱 ($b) 和副檔名 ($e)。 $b 然後將所有句點 ( .
) 替換為底線。最後,$_
設定為"$b.$e"
。
輸出(帶有-v
詳細選項):
$ touch top_axi_256_wrapper_05.02.01.14.00_sample06.tgz \
top_axi_128_wrapper_05.02.01.14.00_sample06.tgz \
a72_a_0.0.0_0.00.04_ac_dc.tgz
$ rename -v 'my($b,$e) = m/^(.*)\.([^.]+)$/; $b =~ s/\./_/g; $_="$b.$e"' *
a72_a_0.0.0_0.00.04_ac_dc.tgz renamed as a72_a_0_0_0_0_00_04_ac_dc.tgz
top_axi_128_wrapper_05.02.01.14.00_sample06.tgz renamed as top_axi_128_wrapper_05_02_01_14_00_sample06.tgz
top_axi_256_wrapper_05.02.01.14.00_sample06.tgz renamed as top_axi_256_wrapper_05_02_01_14_00_sample06.tgz
-n
順便說一句,在測試你的陳述時使用rename
。更多來自man rename
:
-n,-諾諾
無操作:列印要重新命名的檔案的名稱,但不重新命名。
perlrename
可用於大多數發行版(例如rename
Debian 中的軟體包),或來自https://metacpan.org/release/File-Rename