我有大约一千个文件,它们看起来都是这样的:
20091208170014.nc
20091211150704.nc
20091214131328.nc
20091217111953.nc
20091220092643.nc
20091223073308.nc
20091226053932.nc
20091229034557.nc
20091208171946.nc
20091211152610.nc
前八位是日期,后六位是连续数字,但这些数字之间的差异在文件之间并不相同。我希望最后六个数字是连续的并且始终具有相同的步骤。例如:
20091208000001.nc
20091211000002.nc
20091214000003.nc
20091217000004.nc
20091220000005.nc
20091223000006.nc
20091226000007.nc
20091229000008.nc
20091208000009.nc
20091211000010.nc
mmv
我使用和其他类似的方法检查了该网站上的几个问题https://www.ostechnix.com/how-to-rename-multiple-files-at-once-in-linux/但他们都无法向我解释如何在我的名字中包含连续的数字。
为了将其与问题区分开来批量将文件重命名为连续编号,顺序排序必须基于最后六位数字,完全忽略前八个字符中嵌入的日期。
答案1
如果您安装了perl
基于 - 的rename
工具(有时称为 ),prename
您可以在一行中完成此操作,如下所示
rename -n 's/^(.{8})(.{6})\.(.*)/sprintf "%s%06d.%s", $1, ++$a, $3/e' *.nc
正如所写的,它只会告诉您它会做什么。当您满意时,删除-n
静默运行,或将其替换为-v
看看发生了什么。
如果您好奇,这将替换三个(..)
部分(其中.{n}
代表n
字符,.*
代表任何事物,并且括号创建一个分组),其格式化打印结果包括第一组和递增的六位数字。 (不使用第二个分组。)第三个分组包含文件扩展名。
我应该指出,它将拒绝覆盖现有文件。
样本输出
20091208170014.nc renamed as 20091208000001.nc
20091208171946.nc renamed as 20091208000002.nc
20091211150704.nc renamed as 20091211000003.nc
20091211152610.nc renamed as 20091211000004.nc
20091214131328.nc renamed as 20091214000005.nc
20091217111953.nc renamed as 20091217000006.nc
20091220092643.nc renamed as 20091220000007.nc
20091223073308.nc renamed as 20091223000008.nc
20091226053932.nc renamed as 20091226000009.nc
20091229034557.nc renamed as 20091229000010.nc
您似乎希望基于文件名的最后六位数字进行排序,完全忽略嵌入的日期。这里有几个选项。
如果文件数量足够少,shell 可以完全扩展列表,则对文件进行排序:
rename -n '..as above..' $(ls -d *.nc | sort -k1.9,1.14n)
执行转换,使排序键暂时放在文件名的前面,然后重命名,然后替换到它所属的位置:
# Swap the first eight and second six groups around rename -n 's/^(.{8})(.{6})\.(.*)/$2$1.$3/' *.nc # Apply the transform with the shell sorting by original sequence rename -n 's/^(.{6})(.{8})\.(.*)/sprintf "%06d%s.%s", ++$a, $2, $3/e' *.nc # Swap back the first six and second eight groups rename -n 's/^(.{6})(.{8})\.(.*)/$2$1.$3/' *.nc
和以前一样,删除-n
以静默运行或替换它以-v
查看实际发生的情况。
答案2
在 bash 中,并且没有碰撞检查:
index=1
for file in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].nc
do
mv -- "$file" "${file:0:8}"$(printf "%06d" "$index").nc
((++index))
done
通配符[0-9]...
选取包含 8+6 (14) 位数字且后跟.nc
.它循环遍历所有这些文件并重命名它们。目标文件名由三部分生成:
"${file:0:8}"
-- 现有文件名的前 8 个字符(日期)$(printf "%06d" "$index")
-- 6 位零填充索引.nc
-- 现有的扩展
当我在示例文件上运行上述循环的“echo”版本时,我得到:
mv -- 20091208170014.nc 20091208000001.nc
mv -- 20091208171946.nc 20091208000002.nc
mv -- 20091211150704.nc 20091211000003.nc
mv -- 20091211152610.nc 20091211000004.nc
mv -- 20091214131328.nc 20091214000005.nc
mv -- 20091217111953.nc 20091217000006.nc
mv -- 20091220092643.nc 20091220000007.nc
mv -- 20091223073308.nc 20091223000008.nc
mv -- 20091226053932.nc 20091226000009.nc
mv -- 20091229034557.nc 20091229000010.nc