Vim的 source 命令(缩写形式 :so)用于执行外部文件中保存的Vim命令列表(包括命令行模式下的Ex命令和普通模式下的命令),实现批量或重复完成某种操作。

一、source命令简介

:source {file} 用于从 {file} 指定的文件中读取每一行Vim Ex 命令并执行;:source! {file} 用于从 {file} 指定的文件中读取每一行 Vim 普通模式命令并执行。

:source {file} 会在Vim命令行模式下执行 {file} 中的命令列表,而 :source! {file} 则是在Vim普通模式下执行 {file} 中的命令列表。

二、source命令使用举例

Vim入门级配置一文中介绍的各种保存在 ~/.vimrc 文件中的配置项,其实就是通过 :source ~/.vimrc 来使得各配置项生效的。

除了将Vim配置保存在文件中以便永久生效外,还可以在文件中保存多个Vim命令,再通过 source 命令在多个目标文件中一次性执行完所有操作。

例如,由于最近新浪微博开启了防盗链检测,导致Vim教程网所有的教程图片都无法在博客文章中正常显示,不得不迫使我将所有图片迁移到新的图床 (github pages)。

完成图片迁移需要先从微博图床上下载原始图片再上传图片到新的图床上,最后再将博客源文件中的图片地址替换成新图床的地址。Vim教程网已经写了近90篇博客,如果纯手工完成下载、上传、替换的迁移流程,显然是一种非常低效率的体力劳动。

本文介绍使用Vim的source命令辅助完成新浪微博图床的图片迁移工作。

2.1 提取所有博客地址

Python脚本download_sinaimg.py可提取出一篇博文中所有保存在新浪微博上的图片,例如,python download_sinaimg.py https://vimjc.com/vim-color-schemes.html 会下载15个Vim配色方案的图片并保存到当前目录的 images 文件夹中。

为了获取到Vim教程网所有博文的地址,首先使用Vim打开站点地图文件 sitemap.xml 后,再在Vim的命令行模式下执行 :source get_blog_url.vim 即可从 sitemap.xml 文件中提取出所有博客文章的链接。get_blog_url.vim 文件的内容如下:

1
2
3
4
" get_blog_url.vim "
v/loc/d
/\v *\<\/?\w+\>
%s///g

关于 get_blog_url.vim 脚本中各命令的含义及功能,推荐阅读使用Vim处理文本进行详细分析。

此外,下载图片的Python脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# -*- coding: UTF-8 -*-
# author: https://vimjc.com

import os
import re
from sys import argv
import urllib

def getHtml(url):
page = urllib.urlopen(url)
return page.read()

def getImg(html):
reg = r'src="([.*\S]*\.sinaimg.[.*\S]*)"'
imgre = re.compile(reg);
return re.findall(imgre, html)

def downloadFile(url):
html = getHtml(url).decode('UTF-8')
imgList = getImg(html)
for imgPath in imgList:
filename = os.path.basename(imgPath)
print "download file \"%s\" from \"%s\"" % (filename, imgPath)
try:
f = open('./images/'+ filename, 'wb')
f.write((urllib.urlopen(imgPath)).read())
f.close()
except Exception as e:
print("download " imgPath + " error")

if __name__ == '__main__':
downloadFile(argv[1])
2.2 替换图片地址

为了将所有博客源文件中的 “wx1.sinaimg.cn/large”、”wx2.sinaimg.cn/large”、”wx4.sinaimg.cn/large” 等地址全部替换成 “image.vimjc.com/images”,首先使用 vim source/_post/*.md 打开了hexo博客的所有markdown源文件,再通过执行 :argdo source replace_sinaimg_url.vim 对Vim参数列表中的每一个文件都执行 replace_sinaimg_url.vim 中的 Ex 命令。

“replace_sinaimg_url.vim” 文件中保存的Vim命令列表如下所示,提供的功能是:先使用Vim查找命令 / 查找到需要替换的原始串,再使用 substitute 替换命令进行全局替换。

1
2
3
4
" replace_sinaimg_url.vim "
/wx[0-9].sinaimg.cn\/large
%s//image.vimjc.com\/images/g
write

上述流程的Vim视频教程截图如下所示:

vim-argdo-source

关于 Vim参数列表和 :argdo 命令的功能介绍,推荐阅读Vim参数列表args和argdo命令


:通过微博图床迁移来举例说明source命令的使用只是为了说明source命令的用途及可行性。在实践中,如果需要实现一系列的复杂操作,一般会通过其他脚本语言(如Python、shell等)完成。

嗯,扫一扫就可以找到小女子我啦~