批量命令

平日学艺不精,请教各位如何按某种模式批量修改文件名。文件夹中的所有图片名为:1.1.jpg,我需要改成c1_1.jpg。请教这个bash命令该怎么写?

来来来,详细描述一下问题:

你是打算把名为 [任意位纯数字].[任意位纯数字].jpg 的所有文件重命名为 c[任意位纯数字]_[任意位纯数字].jpg 吗?

是的。

版本1

for eachfile in *jpg; do mv $eachfile c${eachfile/./_}; done

 

版本2

ls -1 *jpg | awk '{print("mv "$1" c"$1)}' | sed 's/\./_/3' | bash

 

不过个人习惯用一门高级脚本语言如 Python, Perl 或 Ruby 来做这些事

进行批量命名时,建议先查看即将运行的命令,确认无误后再执行。如在版本 2 中,将末尾的重定向到 bash 去掉,命令将被打印出来供您确认
在版本 1 中,可先将 do mv .... 改为 do echo mv ....

1 个赞

感谢vickycq指导。

孔子曰

$touch '/home/englianhu/下载/新建∙文件夹/文本∙文件 (0).xxx'
$touch '/home/englianhu/下载/新建∙文件夹/文本∙文件 (1).xxx'
$touch '/home/englianhu/下载/新建∙文件夹/文本∙文件 (2).xxx'
$touch '/home/englianhu/下载/新建∙文件夹/文本∙文件 (3).xxx'
$ find . -name 文本∙文件*.xxx | sed -i 's/\(.*\)件/\1稿/g'sed: 没有输入文件
$ find . -name 文本∙文件*.xxx | awk '{print("mv "$0" "$0)}' | sed 's/\(.*\)件/\1 稿/p'
mv ./下载/新建∙文件夹/文本∙文件 (1).xxx ./下载/新建∙文件夹/文本∙文 稿 (1).xxx
mv ./下载/新建∙文件夹/文本∙文件 (1).xxx ./下载/新建∙文件夹/文本∙文 稿 (1).xxx
mv ./下载/新建∙文件夹/文本∙文件 (2).xxx ./下载/新建∙文件夹/文本∙文 稿 (2).xxx
mv ./下载/新建∙文件夹/文本∙文件 (2).xxx ./下载/新建∙文件夹/文本∙文 稿 (2).xxx
mv ./下载/新建∙文件夹/文本∙文件 (3).xxx ./下载/新建∙文件夹/文本∙文 稿 (3).xxx
mv ./下载/新建∙文件夹/文本∙文件 (3).xxx ./下载/新建∙文件夹/文本∙文 稿 (3).xxx
mv ./下载/新建∙文件夹/文本∙文件 (0).xxx ./下载/新建∙文件夹/文本∙文 稿 (0).xxx
mv ./下载/新建∙文件夹/文本∙文件 (0).xxx ./下载/新建∙文件夹/文本∙文 稿 (0).xxx
$ find . -name 文本∙文件*.xxx | awk '{print("mv "$0" "$0)}' | sed 's/\(.*\)件/\1 稿/p' | bash
bash:行1: 未预期的符号“(”附近有语法错误
bash:行1: `mv ./下载/新建∙文件夹/文本∙文件 (1).xxx ./下载/新建∙文件夹/文本∙文 稿 (1).xxx'
$ find . -name 文本∙文件*.xxx | awk '{print("mv "$0" "$0)}' | sed -i 's/\(.*\)件/\1稿/'
sed: 没有输入文件
$ find . -name 文本∙文件*.xxx | awk '{print("\"mv "$0" "$0"\"")}' | sed 's/\(.*\)件/\1稿/'
"mv ./下载/新建∙文件夹/文本∙文件 (1).xxx ./下载/新建∙文件夹/文本∙文稿 (1).xxx"
"mv ./下载/新建∙文件夹/文本∙文件 (2).xxx ./下载/新建∙文件夹/文本∙文稿 (2).xxx"
"mv ./下载/新建∙文件夹/文本∙文件 (3).xxx ./下载/新建∙文件夹/文本∙文稿 (3).xxx"
"mv ./下载/新建∙文件夹/文本∙文件 (0).xxx ./下载/新建∙文件夹/文本∙文稿 (0).xxx"
$ find . -name 文本∙文件*.xxx | awk '{print("\"mv "$0" "$0"\"")}' | sed -i 's/\(.*\)件/\1稿/'
sed: 没有输入文件
$ find . -name 文本∙文件*.xxx | awk '{print("\"mv "$0" "$0"\"")}' | sed -i 's/\(.*\)件/\1稿/g'
sed: 没有输入文件
$ find . -name 文本∙文件*.xxx | awk '{print("\"mv "$0" "$0"\"")}' | sed 's/\(.*\)件/\1稿/g'
"mv ./下载/新建∙文件夹/文本∙文件 (1).xxx ./下载/新建∙文件夹/文本∙文稿 (1).xxx"
"mv ./下载/新建∙文件夹/文本∙文件 (2).xxx ./下载/新建∙文件夹/文本∙文稿 (2).xxx"
"mv ./下载/新建∙文件夹/文本∙文件 (3).xxx ./下载/新建∙文件夹/文本∙文稿 (3).xxx"
"mv ./下载/新建∙文件夹/文本∙文件 (0).xxx ./下载/新建∙文件夹/文本∙文稿 (0).xxx"
$ find . -name 文本∙文件*.xxx | awk '{print("\"mv "$0" "$0"\"")}' | sed 's/\(.*\)件/\1稿/' | bash
bash:行1: mv ./下载/新建∙文件夹/文本∙文件 (1).xxx ./下载/新建∙文件夹/文本∙文稿 (1).xxx: 没有那个文件或目录
bash:行2: mv ./下载/新建∙文件夹/文本∙文件 (2).xxx ./下载/新建∙文件夹/文本∙文稿 (2).xxx: 没有那个文件或目录
bash:行3: mv ./下载/新建∙文件夹/文本∙文件 (3).xxx ./下载/新建∙文件夹/文本∙文稿 (3).xxx: 没有那个文件或目录
bash:行4: mv ./下载/新建∙文件夹/文本∙文件 (0).xxx ./下载/新建∙文件夹/文本∙文稿 (0).xxx: 没有那个文件或目录

出处:将谷歌相册移至猫城项目 · Issue #3 · englianhu/img · GitHub

遇到个正则表达式相关作业,请指点。

空格啥的没处理好造成的。给参数加上引号吧。

另外建议用 rename 命令,更方便。

1 个赞

刚学习礼逆袭,别见笑。

$ touch '/home/englianhu/下载/新建∙文件夹/文本∙文件 (0).xxx'  '/home/englianhu/下载/新建∙文件夹/文本∙文件 (1).xxx' '/home/englianhu/下载/新建∙文件夹/文本∙文件 (2).xxx' '/home/englianhu/下载/新建∙文件夹/文本∙文件 (3).xxx'
$ find $(pwd) -name 文本∙文件*.xxx | awk '{print("mv -f \""$0"\" \""$0"\"")}' | sed 's/\(.*\)件/\1稿/'
$ find $(pwd) -name 文本∙文件*.xxx | awk '{print("mv -f \""$0"\" \""$0"\"")}' | sed 's/\(.*\)件/\1稿/' | bash
$ sudo rm -rf '/home/englianhu/下载/新建∙文件夹/文本∙文稿 (0).xxx' '/home/englianhu/下载/新建∙文件夹/文本∙文稿 (1).xxx' '/home/englianhu/下载/新建∙文件夹/文本∙文稿 (2).xxx' '/home/englianhu/下载/新建∙文件夹/文本∙文稿 (3).xxx'

出处:将谷歌相册移至猫城项目 · Issue #3 · englianhu/img · GitHub

用 bash 重命名文件比较麻烦,而且容易出错,我推荐一个 GUI 应用 KRename,kde 团队出品,个人感觉挺好用的。

一般重命名这种操作,我用文件管理器就处理了,不用脚本。

比如说DoubleCommander我就觉得不错,有七八分windows下TotalCommander的样子了。