前言:今天有一个小插曲,需要将某一目录下所有文件名中 xxx_collect_xxx 中的 collect 修改为 mapping_mrg ,还好我要修改的只有四个,但重复的4次mv命令还是让人头大,所以就考虑有没有什么方法可以一次性修改这里面所有相关文件的文件名,毕竟如果下次是40个文件呢?
vim命令行模式 & vim下调用shell命令
- 在vim下输入
:
就会进入命令行模式,使用vim内置命令可以很方便进行一些操作。比如:set list
显示vim不可见字符;:set fileencoding
查看文件编码格式;:%s/string1/string2
将当前文件中每一行出现的第一个string1替换为string2;使用 & 可以引用string1的内容,比如:%s/string1/m&
string1将被替换为 mstring1:%s/string1/string2/g
将所有string1替换为string2 - vim下调用shell命令:
:!{cmd}
会将cmd执行结果显示在标准输出上;:read !{cmd}
将cmd执行结果重定向到当前vim缓冲中;:write !{cmd}
将当前vim缓冲作为cmd输入,比如执行:write !sh
会将当前vim中每行作为shell命令并执行。
Vim执行shell命令及使用Vim批量更改文件名
正则表达式匹配任意字符 & 分组捕获和反向引用
-
.
匹配单个字符*
匹配前面那个字符任意多次.*
匹配任意多个字符,很常用 - 分组捕获
基础正则中,使用括号可以对匹配内容进行分组并暂时保存,分组后会有分组编号,可以使用反斜线加编号\N
的方式反向引用这些分组。
比如对于xxx_collect_xxx,就可以表示为 (.*)collect(.*) ,用\1
表示collect前面的部分,用\2
表示collect后面的部分
基础正则表达式
利用 vim 批量修改文件名
有了上面的基础知识,前言部分的内容也就容易做到了。
- 终端执行
vim
打开vim页面,执行:read !ls *collect*
列出当前目录所有名称中包含collect的文件名,并将结果重定向到当前vim缓冲 -
:0d
目的是删除第一个空行 -
:%s/\(.*\)collect\(.*\)/mv & \1mapping_mrg\2/g
结合了%s替换命令和正则表达式。\(.*\)
中\
作为转义字符转义(
和)
,最终vim缓冲的内容就变成了mv xxx_collect_xxx xxx_mapping_xxx
-
:write !sh
将vim缓冲内容作为shell命令执行,最后:q!
退出vim,当前目录已经完成修改!