假如你有一个多层级文件夹,它包含了很多jpg文件以及子文件夹(也有jpg文件)。现在你想把所有文件批量重命令,比如把jpg扩展名改为png,或者把里面的IMG字符改为abc,可以用下面的命令。
新建一个文件(比如file.sh),内容如下,并用chmod a+x file.sh
命令赋予可执行权限。
#!/bin/bash
find . -type f -name '*.jpg' -exec sh -c '
for f; do mv "$f" "${f//.jpg/.png}";
done' sh {} +
从左到右依次解释如下
-
find
文件查找命令 -
.
代表从当前目录中查找,可改为要查找的目录 -
-type f
指定查找的文件类型,f
代表普通文件regular file;如果只查找目录,可以用d
-
-name '*.jpg'
指定要查找的文件名,注意这里要区分大小写
!如果不需要区分大小写的话,用-iname
。后面的'*.jpg'
使用了通配符,*
表示任意长度的字符,?
表示单个字符。注意:要使用引号把文件名保护起来 -
-exec COMMAND {} +
针对所有符合条件的文件,执行它后面的命令,下面详细解释后面的命令: -
sh -c
提供了一个受保护的命令环境(contained environment context
),-c
后面跟着要执行的命令,如果不用-c
的话,会进入用户交互模式,等待用户输入命令。 -
for f; do COMMAND; done
命令解释:用for
命令遍历前面find
命令的查找结果,依次把某个结果放在变量f
中,然后在COMMAND
中对f
进行操作,比如ls $f
-
mv "$f" "${f//.jpg/.png}"
:这里执行的是重命名mv
的操作,"$f"
是旧的文件名,在构建新的文件名时,进行了替换操作,把.jpg
替换成.png
。注意:假如文件名中有多个.jpg
,如果只想替换第一个匹配字符,使用"${f/.jpg/.png}"
;如果想替换所有的匹配字符,使用"${f//.jpg/.png}"
。差别在于f
后面是一个/
(单次)还是两个/
(全局)。
另外:
-
如果想指定目录深度(比如2级),可以使用
-maxdepth 2
,如果设置为1
则只查找当前目录。 -
关于
-exec command {} +
的详细说明,参考这里:
-exec command {} +
This variant of the -exec option runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of '{}' is allowed within the command. The command is executed in the starting directory.
在macOS 10.13.6 High Sierra上测试通过。
网友评论