Linux shell脚本将前导零添加到文件名

我有一个约1700个文件的文件夹。 他们都被命名为1.txt1497.txt等,我想重新命名所有的文件,所有的文件名是四位数字。

即, 23.txt变成0023.txt

什么是一个shell脚本会做到这一点? 或者一个相关的问题:我如何使用grep来匹配包含\d.txt (即一个数字,然后是句点,然后是字母txt )?

以下是我到目前为止:

 for a in [command i need help with] do mv $a 000$a done 

基本上,运行三次,用命令find一个数字,两个数字和三个数字的文件名(初始零的数量改变)。

尝试:

 for a in [0-9]*.txt; do mv $a `printf %04d.%s ${a%.*} ${a##*.}` done 

根据需要更改文件名模式( [0-9]*.txt )。


通用枚举重命名不会对最初的一组文件名进行假设:

 X=1; for i in *.txt; do mv $i $(printf %04d.%s ${X%.*} ${i##*.}) let X="$X+1" done 

在同一主题上:

  • Bash脚本来填充文件名
  • 在bash中提取文件名和扩展名

使用有时与Perl一起安装的rename (在某些情况下为prename )脚本,可以使用Perlexpression式来进行重命名。 脚本跳过重命名,如果有名称冲突。

下面的命令只重命名具有四位或更less位数的文件,后面跟一个“.txt”扩展名。 它不会重命名不严格符合该模式的文件。 它不会截断包含四位数以上的名称。

 rename 'unless (/0+[0-9]{4}.txt/) {s/^([0-9]{1,3}\.txt)$/000$1/g;s/0*([0-9]{4}\..*)/$1/}' * 

几个例子:

 Original Becomes 1.txt 0001.txt 02.txt 0002.txt 123.txt 0123.txt 00000.txt 00000.txt 1.23.txt 1.23.txt 

到目前为止给出的其他答案将尝试重命名不符合该模式的文件,产生包含非数字字符的文件名的错误,执行产生名称冲突的重命名,尝试和无法重命名名称中有空格的文件,以及可能还有其他问题

 for a in *.txt; do b=$(printf %04d.txt ${a%.txt}) if [ $a != $b ]; then mv $a $b fi done 

一内胆:

 ls | awk '/^([0-9]+)\.txt$/ { printf("%s %04d.txt\n", $0, $1) }' | xargs -n2 mv 

如何使用grep只匹配包含\ d.txt(IE 1位,然后是句点,然后是字母txt)的行?

 grep -E '^[0-9]\.txt$' 

假设你的文件夹中有数据types为.dat的文件。 只需将此代码复制到名为run.sh的文件中,通过运行chmode +x run.sh使其可执行,然后使用./run.sh执行:

 #!/bin/bash num=0 for i in *.dat do a=`printf "%05d" $num` mv "$i" "filename_$a.dat" let "num = $(($num + 1))" done 

这会将文件夹中的所有文件转换为filename_00000.datfilename_00001.dat

此版本还支持在数字之前(之后)处理string。 但基本上你可以做任何正则expression式匹配+ printf,只要你的awk支持它。 它也支持文件名中的空白字符(除了换行符)。

 for f in *.txt ;do mv "$f" "$( awk -vf="$f" '{ if ( match(f, /^([a-zA-Z_-]*)([0-9]+)(\..+)/, a)) { printf("%s%04d%s", a[1], a[2], a[3]) } else { print(f) } }' <<<'' )" done 

要只匹配单个数字的文本文件,你可以做…

 $ ls | grep '[0-9]\.txt' 

单线提示:

 while [ -f ./result/result`printf "%03d" $a`.txt ]; do a=$((a+1));done RESULT=result/result`printf "%03d" $a`.txt 

为了提供一个解决scheme,即使在存在空格的文件名的情况下,也要谨慎地编写正确的解决scheme:

 #!/usr/bin/env bash pattern='%04d' # pad with four digits: change this to taste # enable extglob syntax: +([[:digit:]]) means "one or more digits" # enable the nullglob flag: If no matches exist, a glob returns nothing (not itself). shopt -s extglob nullglob for f in [[:digit:]]*; do # iterate over filenames that start with digits suffix=${f##+([[:digit:]])} # find the suffix (everything after the last digit) number=${f%"$suffix"} # find the number (everything before the suffix) printf -v new "$pattern" "$number" "$suffix" # pad the number, then append the suffix if [[ $f != "$new" ]]; then # if the result differs from the old name mv -- "$f" "$new" # ...then rename the file. fi done