参考链接:https://zhuanlan.zhihu.com/p/68111471
需求
假设有如下文件目录结构,a
中是修改好之后的文件,b
中是需要修改的文件。
[adams@localhost test]$ ls
a b
[adams@localhost test]$ tree
.
├── a
│ └── qqq
│ └── www
│ └── eee
│ ├── asdf.ww
│ ├── dfdfeyg.aa
│ ├── dfdfgdfdf.bb
│ ├── dfgh.www
│ ├── fddf.aa
│ ├── hjkl.ww
│ ├── sdfg.ww
│ ├── vbnm.qq
│ ├── xcvb.qq
│ └── zxcv.ww
└── b
├── fddf.aa
├── hjkl.ww
└── ppp
├── kkk
│ ├── ggg
│ │ ├── xcvb.qq
│ │ └── zxcv.ww
│ ├── sdfg.ww
│ └── vbnm.qq
└── lll
├── dfdfeyg.aa
├── dfdfgdfdf.bb
└── fff
├── asdf.ww
└── dfgh.www
10 directories, 20 files
[adams@localhost test]$
需要把a
中文件,拷贝到对应文件的对应目录中。
因为文件较多,考虑写个脚本自动执行。需要做两件事:
1、确定a
中文件的目录。
2、确定b
中文件的目录。
第一件容易实现,文件都在统一个目录下:/home/adams/test/a
中的qqq/www/eee/
目录中。
第二件也容易实现,通过find
命令的返回值,也可以获取b
中对应文件的目录。如下所示:
[adams@localhost b]$ find -name "sdfg.ww"
./ppp/kkk/sdfg.ww
[adams@localhost b]$
所以只需要写成:
[adams@localhost b]$ cp /home/adams/test/a/qqq/www/eee/asdf.ww `find -name asdf.ww`
即可完成复制。
但是:
写.sh
文件时,会有很多重复的工作,比如需要复制最后的文件名给find
命令使用。如果有几十个,上百个文件,工作量也不小。所以需要记录一下重复的工作,批量执行。
实现记录重复工作,并执行的功能,可以用到Vim
自带的”宏录制“功能。
vim 宏录制:
制作宏:
1、在正常模式下,按q
,开始录制。
2、按 x(其他字母也可以,a,b,c都可以),给当前录制的宏起个名字:x。
3、执行需要重复操作的动作。
4、按q
结束宏录制。
使用宏:
在正常模式下,按@x
,既可执行x
宏。
按@@
可以重复执行上次执行的宏动作。
下面开始处理上面的问题:
1、通过:find -name "*"
命令可以得到:
[adams@localhost a]$ find -name "*"
.
./qqq
./qqq/www
./qqq/www/eee
./qqq/www/eee/asdf.ww
./qqq/www/eee/sdfg.ww
./qqq/www/eee/dfgh.www
./qqq/www/eee/zxcv.ww
./qqq/www/eee/xcvb.qq
./qqq/www/eee/vbnm.qq
./qqq/www/eee/hjkl.ww
./qqq/www/eee/fddf.aa
./qqq/www/eee/dfdfgdfdf.bb
./qqq/www/eee/dfdfeyg.aa
[adams@localhost a]$
初始脚本内容:
[adams@localhost b]$ ls
fddf.aa hjkl.ww hong.sh ppp
[adams@localhost test]$ cat hong.sh
./qqq/www/eee/asdf.ww
./qqq/www/eee/sdfg.ww
./qqq/www/eee/dfgh.www
./qqq/www/eee/zxcv.ww
./qqq/www/eee/xcvb.qq
./qqq/www/eee/vbnm.qq
./qqq/www/eee/hjkl.ww
./qqq/www/eee/fddf.aa
./qqq/www/eee/dfdfgdfdf.bb
./qqq/www/eee/dfdfeyg.aa
[adams@localhost test]$
开始录制宏:
1、在正常状态下,按q
,然后按x
:
2、当前光标定位到首行,我们以首行为例。
-
按
end
(也可以是其他快捷键:),到行尾 -
按
b
到asdf.ww
中的w
-
按
b
到asdf.ww
中的.
-
按
b
到asdf.ww
中的a
-
按
y
$
,拷贝当前位置到行尾的内容 -
按
end
,到行尾 -
按
i
,进入输入模式 -
按空格,输入一个空格
-
按
Esc
,退出输入模式 -
按
p
,粘贴刚才复制的内容 -
按
Home
键到行首 -
按下箭头键,进入到下一行。(这一步很重要)
-
按
q
键,结束录制宏。使用宏:
1、到第二行,正常模式下,按
@x
,执行刚才录制的宏x
。2、到下一行,正常模式下,按
@@
,执行刚才执行的宏x
。(该步骤可省略)3、到下一行,正常模式下,按
8@@
,执行刚才的宏8
次。
宏录制的功能就说完了。下面的操作就没有什么技术含量了。简单说下。
1、命令模式下:%s/ / ` find -name /g :
2、%s/$/`/g:给行尾加上
3、在行首加上a目录的绝对路径和cp命令:%s/^/cp /home/test/a//g
完成后: