[test@localhost rename]$ ll
total 0
-rw-rw-r--. 1 test test 0 Sep 11 09:07 afile-1.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 bfile-10.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 cfile-123.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 dfile-4711.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 efile-20191201.txt
假如存在以上文件,现在需要统一修改文件的名称格式,结果如下
[test@localhost rename]$ ll
total 0
-rw-rw-r--. 1 test test 0 Sep 11 09:07 afile-00000001.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 bfile-00000010.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 cfile-00000123.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 dfile-00004711.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:07 efile-20191201.txt
通过find命令查找文件、再通过awk处理格式。
find . -name "*.txt" | awk -F'[-.]' -v mvCmd='mv -n "%s" "%s"\n' \
'{ num = $(NF-1);
files[$0] = num;
max = num > max? num : max;
}
END { width = length(max);
for(name in files) {
old = new = name;
formattedNum = sprintf("%0*d", width, files[name]);
sub(files[name],formattedNum,new);
printf mvCmd,old,new;
}
}' | sh
[test@localhost rename]$ find . -name "*.txt"
./afile-1.txt
./bfile-10.txt
./cfile-123.txt
./dfile-4711.txt
./efile-20191201.txt
afile-1.txt
可以被拆分为afile
、1
和txt
三个部分,在awk的脚本中就可以通过$(NF)
获取最后一个值,也就是txt,而通过$(NF-1)
则可以获取倒数第二个值,在这里就是1
。$0
则是文件的完整名称。[test@localhost rename]$ find . -name "*.txt" | awk -F'[-.]' -v cmd1='key = "%s" ,value = "%s"\n' -v cmd2=' width = "%s"\n' \
> '{ num = $(NF-1);
> files[$0] = num;
> max = num > max? num : max;
> }
> END { width = length(max);
> for(name in files) {
> printf cmd1,name,files[name];
> }
> printf cmd2,width;
> }'
key = "./cfile-123.txt" ,value = "123"
key = "./dfile-4711.txt" ,value = "4711"
key = "./efile-20191201.txt" ,value = "20191201"
key = "./bfile-10.txt" ,value = "10"
key = "./afile-1.txt" ,value = "1"
width = "8"
通过哈希表files收集了文件名称以及数字部分的映射关系以及数字部分的最长长度为8.
3. 通过格式化工具生成mv命令。首先将文件名称赋值给old和new变量,然后根据最大长度和当前长度计算格式化的数字并赋值给formattedNum变量。
[test@localhost rename]$ find . -name "*.txt" | awk -F'[-.]' -v cmd1='key = "%s" ,value = "%s",old = "%s",new = "%s",formattedNum = "%s"\n' -v cmd2=' width = "%s"\n' \
> '{ num = $(NF-1);
> files[$0] = num;
> max = num > max? num : max;
> }
> END { width = length(max);
> for(name in files) {
> old = new = name;
> formattedNum = sprintf("%0*d", width, files[name]);
> sub(files[name],formattedNum,new);
> printf cmd1,name,files[name],old,new,formattedNum;
> }
> printf cmd2,width;
> }'
key = "./cfile-123.txt" ,value = "123",old = "./cfile-123.txt",new = "./cfile-00000123.txt",formattedNum = "00000123"
key = "./dfile-4711.txt" ,value = "4711",old = "./dfile-4711.txt",new = "./dfile-00004711.txt",formattedNum = "00004711"
key = "./efile-20191201.txt" ,value = "20191201",old = "./efile-20191201.txt",new = "./efile-20191201.txt",formattedNum = "20191201"
key = "./bfile-10.txt" ,value = "10",old = "./bfile-10.txt",new = "./bfile-00000010.txt",formattedNum = "00000010"
key = "./afile-1.txt" ,value = "1",old = "./afile-1.txt",new = "./afile-00000001.txt",formattedNum = "00000001"
width = "8"
最后生成命令对应的字符串
[test@localhost rename]$ find . -name "*.txt" | awk -F'[-.]' -v mvCmd='mv -n "%s" "%s"\n' \
> '{ num = $(NF-1);
> files[$0] = num;
> max = num > max? num : max;
> }
> END { width = length(max);
> for(name in files) {
> old = new = name;
> formattedNum = sprintf("%0*d", width, files[name]);
> sub(files[name],formattedNum,new);
> printf mvCmd,old,new;
> }
> }'
mv -n "./cfile-123.txt" "./cfile-00000123.txt"
mv -n "./dfile-4711.txt" "./dfile-00004711.txt"
mv -n "./efile-20191201.txt" "./efile-20191201.txt"
mv -n "./bfile-10.txt" "./bfile-00000010.txt"
mv -n "./afile-1.txt" "./afile-00000001.txt"
[test@localhost rename]$ find . -name "*.txt" | awk -F'[-.]' -v mvCmd='mv -n "%s" "%s"\n' \
> '{ num = $(NF-1);
> files[$0] = num;
> max = num > max? num : max;
> }
> END { width = length(max);
> for(name in files) {
> old = new = name;
> formattedNum = sprintf("%0*d", width, files[name]);
> sub(files[name],formattedNum,new);
> printf mvCmd,old,new;
> }
> }' | sh
mv: ‘./efile-20191201.txt’ and ‘./efile-20191201.txt’ are the same file
[test@localhost rename]$ ll
total 0
-rw-rw-r--. 1 test test 0 Sep 11 09:26 afile-00000001.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:26 bfile-00000010.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:26 cfile-00000123.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:26 dfile-00004711.txt
-rw-rw-r--. 1 test test 0 Sep 11 09:26 efile-20191201.txt