我有以下一组文件
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