使用 vim 快速对当前文件夹下的文件批量重命名
前言
我们在使用Linux的时候,有很多种方法可以对文件进行重命名,例如 命令行 下的mv命令,或者是使用像dolphin这样的图形文件管理器。但是有时候需要对一个文件夹下的所有文件批量重命名,甚至是递归地重命名当前文件夹下所有以.xxx结尾的文件,这时候你还在手动地一遍遍敲mv命令再一遍遍按 TAB 补全么?
图形化的文件管理器
目前 Linux 社区有好多优质的图形化文件管理器,大多数的风格都与 Windows 大相径庭。就拿我现在用的 KDE 出品的 dolphin 来说,基本上 Windows 能做到的它也可以做到,当然 我没有深究其功能,无法评断好用与否。
但是往往这类文件管理器只能做到一些简单的功能,其出现就是为了那些刚从 Windows 转向 Linux 的人不用付出太多的学习成本,至于好不好用则是见仁见智了。
Vim
vim 已经是一个老生常谈的话题了,不管你用没用过也都应该听说过,毕竟曾经有几百万人在互联网上发问 「如何退出 vim 编辑器」......
那么如何实现批量重命名呢?
先看第一个指令 :read
首先打开 vim (这里我用的是 neovim 两者无差别)

尝试下进入 -命令模式- ,输入
:read !ls

敲一下回车就会发现,vim 把 ls 指令所输出的内容打印到了我们的编辑器中,也就是说,你只需要在命令模式中输入上述指令,便可以将 感叹号 ! 后面的命令的输出内容打印到屏幕上。
不妨再试一下,输入
:read !ls -al

Bingo~
再来看下一个指令 :write
我们先来新建一个文件夹: temp,里面放入一些文件,内容如下:
temp > tree
.
├── a.json
├── b.json
├── c.json
└── dir
├── e.json
└── f.json
# 这里的 tree 只是一个指令,功能是以树形展示目录结构
在 temp 文件夹下输入 vim 来启动 vim,按下 冒号 进入 -命令模式-,输入:
:read !find ./
这将会把当前目录下的所有内容打印出来,包括子文件夹下的内容。

我们现在的目的是要把 所有以 .json 结尾的文件改为 .txt 结尾,使用的命令是 mv。
首先,去掉多余的第一行和目录 ./dir,使用 Ctrl + v 进入 -可视块- 模式,再每一行的最前面加上 mv, 再加一个空格。

之后,便可以再后面新增 更改后的名称,这里如果条目少的话可以手敲,但是如果超过十几行的话就要用到 vim 的 宏 了。
这里简单说明下具体的做法,首先放出按键:
q -> a -> $ -> 5h -> yiw -> $ -> a -> [空格] -> Esc -> p -> a -> .txt -> Esc -> j -> q
一遍一遍试的命令,希望老爷们赏个赞 🥺
下面是对每条指令的介绍:
| 指令 | 功能 |
|---|---|
| q | 开始记录 宏 |
| a | 记录宏按键为 a |
| $ | 将光标移动到行尾 |
| 5h | 光标向前移动 5 格 |
| yiw | 复制当前光标所在的单词 |
| $ | 将光标移动到行尾 |
| a | 开始插入 |
| <space> | 插入一个空格 |
| <Esc> | 退回到 -普通- 模式 |
| p | 在光标后粘贴刚才复制的内容 |
| a | 开始插入 |
| .txt | 插入 .txt |
| <Esc> | 退回到 -普通- 模式 |
| j | 光标下移一行 |
| q | 结束录制 宏 |
这样,便实现了下面的效果:

那要怎么执行这几行命令呢?记得我们上面的小标题么?
:write
还是一样,先进入到 -普通- 模式,按一下 冒号 进入 -命令- 模式,输入:
:write !sh
执行一下

虽然改名成功了,但是子目录里的文件全部移动到当前目录下了 😭
(教学事故......)
原因大家也该清楚了,因为 mv 实际上是一个移动文件的指令,我们用它重命名是因为它恰好有这个功能,而在重命名时并没有加目录,所以便会酿成刚刚的惨剧......
没关系,我们再把 e.txt f.txt 移动到 dir 目录下,这次的任务是将 .txt 结尾的文件改成以 .json 结尾。

重复上面的步骤,只是改一下宏命令:
q -> a -> ^ -> f. -> yf. -> $ -> a -> [空格] -> [Esc] -> p -> a -> json -> [Esc] -> j

这回应该没问题了吧,执行一下!
:write !sh

果然,成功改回来了!

浙公网安备 33010602011771号