Shell 多个文件的重命名与移动,移动或重命名多个文件是我们经常会碰到的一项工作。系统管理员经常需要将有相同前缀或相同类型的文件移动到新的目录中。从数码相机中下载的照片可能需要重命名并保存。音乐、视频和E-mail也得定期重新整理。
这些工作都有专门的应用程序来完成,但是我们也可以按照自己的方式编写脚本来实现。让我们看看如何用脚本来执行此类操作。
预备知识
rename
命令利用Perl正则表达式修改文件名。组合find
、rename
和mv
命令,我们能做到的事其实很多。
实战演练
下面的脚本利用find
查找PNG和JPEG文件,然后使用##
操作符和mv
将查找到的文件重命名为image-1.EXT、image-2.EXT等。注意,脚本并不会修改文件的扩展名:
#!/bin/bash
#文件名: rename.sh
#用途: 重命名 .jpg 和 .png 文件
count=1;
for img in `find . -iname '*.png' -o -iname '*.jpg' -type f -maxdepth 1`
do
new=image-count.{img##*.}
echo "Renaming img tonew"
mv "img" "new"
let count++
done
输出如下:
$ ./rename.sh
Renaming hack.jpg to image-1.jpg
Renaming new.jpg to image-2.jpg
Renaming next.png to image-3.png
该脚本重命名了当前目录下所有的.jpg和.png文件,新文件名采用形如image-1.jpg、image-2.jpg、image-3.png、image-4.png的格式。
工作原理
在前面的重命名脚本中使用了for
循环迭代所有扩展名为.jpg或.png的文件。我们使用find
命令展开搜索,选项-o
用于指定多个-iname
选项,后者用于进行大小写无关的匹配。选项-maxdepth 1
仅搜索当前目录,不涉及其中的子目录。
为了跟踪图像编号,我们将变量count
初始化为1
。接下来用mv
命令重命名文件。新的文件名通过${img##*.}
来构造,它能够从当前处理的文件名中解析出扩展名(请参看2.12节中对于 ${img##*.}
的解释)。let count++
用来在每次循环中递增文件编号。
还有其他重命名文件的方法。
- 将
*.JPG
更名为*.jpg
:
$ rename *.JPG *.jpg
- 将文件名中的空格替换成字符
"_"
:
$ rename 's/ /_/g' *
's/ /_/g'
用于替换文件名,而 *
是用于匹配目标文件的通配符,它也可以写成 *.txt
或其他通配符模式。
$ rename 'y/A-Z/a-z/' *$ rename 'y/a-z/A-Z/' *
- 将所有的.mp3文件移入给定的目录:
$ find path -type f -name "*.mp3" -exec mv {} target_dir \;
- 以递归的方式将所有文件名中的空格替换为字符
"_"
:
$ find path -type f -exec rename 's/ /_/g' {} \;