我有类似的文件
file1.txt
file2.txt
file3.txt
...
file11.txt
file12.txt
...
file100.txt
file101.txt
...
我想将它们重命名为具有相同的字符串宽度,例如
file001.txt
file002.txt
file003.txt
...
file011.txt
file012.txt
...
file100.txt
file101.txt
...
有没有一个简单的命令可以实现这一目标?我想避免手动重命名,例如使用 Rangerbulkrename。
答案1
在手册页中rename(1)
,您可以查看一个示例来执行此操作:
EXAMPLES
Given the files foo1, ..., foo9, foo10, ..., foo278, the commands
rename foo foo00 foo?
rename foo foo0 foo??
will turn them into foo001, ..., foo009, foo010, ..., foo278
因此,对于您的情况,简单的解决方案(如果最大数字为 3 位数长)将是:
rename file file00 file?.txt
rename file file0 file??.txt
在运行实际命令之前,您可以通过添加和标志rename
来测试它,看看结果是什么:--no-act / -n
--verbose / -v
$ rename -nv file file00 file?.txt
`file1.txt' -> `file001.txt'
`file2.txt' -> `file002.txt'
`file3.txt' -> `file003.txt'
$ rename -nv file file0 file??.txt
`file11.txt' -> `file011.txt'
`file12.txt' -> `file012.txt'
更通用的解决方案(从bash
3.0 版本开始可用):
$ for i in `find ./ -maxdepth 1 -type f -name 'file*.txt'`; \
do if [[ "$i" =~ file([0-9]*).txt$ ]]; \
then NUM=$(printf "%03d" "${BASH_REMATCH[1]}"); \
echo mv --verbose $i $i ./file${NUM}.txt; \
fi; \
done
mv --verbose ./file1.txt ./file001.txt
mv --verbose ./file2.txt ./file002.txt
mv --verbose ./file3.txt ./file003.txt
mv --verbose ./file11.txt ./file011.txt
mv --verbose ./file12.txt ./file012.txt
mv --verbose ./file100.txt ./file100.txt
mv --verbose ./file101.txt ./file101.txt
echo
当您想要执行更改时删除。这只是一个简单的示例,您也可以在行中将文件的前缀和后缀更改为模式if
,并使用$BASH_REMATCH
捕获这些模式来进行更复杂的重命名。例如:
$ for i in `find ./ -maxdepth 1 -type f`; \
do if [[ "$i" =~ ^([^0-9]*)([0-9]*).txt$ ]]; \
then NUM=$(printf "%03d" "${BASH_REMATCH[2]}"); \
echo mv --verbose $i ${BASH_REMATCH[1]}${NUM}.txt; \
fi; \
done
mv --verbose ./file1.txt ./file001.txt
mv --verbose ./file2.txt ./file002.txt
mv --verbose ./file3.txt ./file003.txt
mv --verbose ./file11.txt ./file011.txt
mv --verbose ./file12.txt ./file012.txt
mv --verbose ./file100.txt ./file100.txt
mv --verbose ./file101.txt ./file101.txt
mv --verbose ./something1.txt ./something001.txt
mv --verbose ./another02.txt ./another002.txt
当然,您可以修改printf
命令,将零填充长度从 3 更改为任何其他数字。
答案2
要将所有 ASCII 十进制数字序列的文件重命名为宽度为 3(带 0)的文件,请使用zsh
:
autoload -Uz zmv
zmv -n '*' '${f//(#m)<->/${(l[3][0])MATCH}}'
(-n
如果对结果满意,请删除进行试运行)。
与基于 Perl 的rename
实现相同(有时称为file-rename
,prename
或perl-rename
):
rename -n 's/\d+/sprintf "%03d", $&/ge' ./*[0123456789]*
答案3
使用 perlrename
实用程序,也称为file-rename
、perl-rename
或prename
。不要将其与具有完全不同且不兼容的功能和命令行选项的rename
实用程序混淆。 util-linux
Perl 重命名允许您使用任意复杂的 Perl 代码来重命名文件,但最常用于对文件名执行简单的sed
类似s/search/replace/
操作。
rename -n 's/^file(\d+)\.txt$/sprintf "file%03i.txt", $1/e' file*.txt
regex修饰符/e
告诉 rename 将 s/search/replace/ 运算符的替换部分视为可执行的 perl 代码。该sprintf
函数用于对 .txt 扩展名之前的数字进行零填充。
或者它可以推广到任何文件名前缀和扩展名 - 例如
rename -n 's/\A(.*?)(\d+)(\..*)\z/sprintf "%s%03i%s", $1, $2, $3/esm' *
/s
和正/m
则表达式修饰符用于确保脚本适用于任何文件名,甚至包含换行符的文件名。 \A
是字符串开头锚点,也是\z
字符串结尾锚点。
请注意,该-n
选项使其成为一次试运行,因此它只会显示它将执行的操作,而不会实际重命名任何文件。当您确认它符合您的要求后,请删除-n
,或将其替换为 以获得详细输出。-v