我要制作一个图像文件的视频,但文件名包含科学计数法的数字,因此名称的顺序不正确。
文件名的格式如下:
ABC_1.000000E-01.png ~ ABC_1.100000E+01.png,
DEF_1.000000E-01.png ~ DEF_1.100000E+01.png,
GHI_1.000000E-01.png ~ GHI_1.100000E+01.png,
.
.
.
如果我更改数字使用的数字表示法,顺序将不再正确,因此我想按如下方式更改它。
ABC_001.png ~ ABC_110.png,
DEF_001.png ~ DEF_110.png,
GHI_001.png ~ GHI_110.png,
.
.
.
我如何在我的 Linux 系统上执行此操作?
答案1
也试试
ls -1 *.png | LC_ALL=C awk -F[._] '{TMP=$2 "." $3; printf "mv %s %s_%03d.%s\n", $0, $1, 10*TMP, $4}'
mv ABC_1.000000E-01.png ABC_001.png
mv ABC_1.100000E+01.png ABC_110.png
mv DEF_1.000000E-01.png DEF_001.png
mv DEF_1.100000E+01.png DEF_110.png
mv GHI_1.000000E-01.png GHI_001.png
mv GHI_1.100000E+01.png GHI_110.png
它用于awk
以科学记数法分离和转换数字,并将其十倍值作为零填充整数输出。例如,sh
如果对结果满意,则通过管道。
答案2
这是一个脚本,它将查找当前目录中的每个 png 文件并相应地重命名它们。请注意,它不会覆盖现有文件。
这是作品预览
./DEF_1.100000E+01.png - ./DEF_11.00.png
./DEF_1.000000E-01.png - ./DEF_0.10.png
./GHI_1.000000E-01.png - ./GHI_0.10.png
./ABC_1.100000E+01.png - ./ABC_11.00.png
./GHI_1.100000E+01.png - ./GHI_11.00.png
./ABC_1.000000E-01.png - ./ABC_0.10.png
脚本之前
$ ls
ABC_1.000000E-01.png DEF_1.000000E-01.png GHI_1.000000E-01.png script.sh
ABC_1.100000E+01.png DEF_1.100000E+01.png GHI_1.100000E+01.png
脚本之后
$ ls
ABC_0.10.png DEF_0.10.png GHI_0.10.png script.sh
ABC_11.00.png DEF_11.00.png GHI_11.00.png
脚本
#!/bin/bash
for file in $(find . -type f -name "*.png")
do
number=$(echo "${file}" | cut -d'_' -f 2)
number=$(basename "${number}" .png)
number=$(echo "${number}" | awk '{ printf("%.2f\n",$1) }')
filename=$(echo "${file}" | cut -d'_' -f 1)
mv -n "${file}" "${filename}_${number}.png"
done
答案3
和zsh
:
$ autoload -Uz zmv
$ zmv -n '(*_)(<->.<->E[+-]<->)(.png)' '$1${(l[3][0])$(( ($2*10)|0 ))}$3'
mv -- ABC_1.000000E-01.png ABC_001.png
mv -- ABC_1.100000E+01.png ABC_110.png
mv -- DEF_1.000000E-01.png DEF_001.png
mv -- DEF_1.100000E+01.png DEF_110.png
mv -- GHI_1.000000E-01.png GHI_001.png
mv -- GHI_1.100000E+01.png GHI_110.png
(-n
如果愿意的话,可以删除以进行试运行)。
perl
与基于 - 的变体类似rename
(有时称为prename
或perl-rename
以消除其与来自 的(不相关且更有限的)rename
命令的歧义util-linux
):
$ rename -n 's{_\K\d+\.\d+E[+-]\d+(?=\.png\Z)}{sprintf "%03d", $&*10}e' ./*.png
rename(./ABC_1.000000E-01.png, ./ABC_001.png)
rename(./ABC_1.100000E+01.png, ./ABC_110.png)
rename(./DEF_1.000000E-01.png, ./DEF_001.png)
rename(./DEF_1.100000E+01.png, ./DEF_110.png)
rename(./GHI_1.000000E-01.png, ./GHI_001.png)
rename(./GHI_1.100000E+01.png, ./GHI_110.png)
两者的相似之处:
- perl
\d+
匹配一个或多个十进制数字,而 zsh<->
匹配表示任何十进制数的字符串(无界限形式<x-y>
),因此本质上是相同的。 sprintf "%03d"
转换为整数并用 0 填充。$(( number|0 ))
在 zsh 中转换为整数,而 则l[3][0]
进行填充。
差异:
zmv
在进行任何重命名之前,将进行完整性检查(例如x_1E+2.png
vs的冲突或已经存在的目标文件)。x_10E+1.png
- zsh 的
l
参数扩展标志会进行填充,但也会截断到指定的宽度。因此,1.2E+3
(1200) 将被截断为200
,而sprintf "%03d"
将其保留为1200
。