过滤程序是一个接受文本作为标准输入(stdin),然后进行某些处理,并把结果放置到标准输出(stdout)的程序。可以理解为,Vim将当前缓冲区同时作为输入和输出,并借助外部程序进行文字处理。例如使用外部sort命令进行排序,然后用输出结果替换当前文本内容。
过滤器命令
使用以下格式的过滤器命令,可以利用外部程序 {filter} 过滤 {motion} 跨越的多行:
:{range}!{motion}{filter}
使用%指代整个文件,可以将所有行的字母转换为大写:
:%!tr [:lower:] [:upper:]
连续点击!!键,将转到屏幕底部继续输入针对当前行的:.!
命令。以下命令将本行的字母转换为大写:
:.!tr [:lower:] [:upper:]
使用以下命令,将指定行的字母转换为大写:
:4,6!tr [:lower:] [:upper:]
通过在命令之前增加数字前缀,也可以实现相同的功能。首先将光标移动到第4行,然后连续点击3!!键,将转到屏幕底部继续输入针对行范围:.,.+2!
的命令。以下命令,将本行及后续2行(共计3行)的字母转换为大写:
:.,.+2!tr [:lower:] [:upper:]
使用以下命令,可以将指定标记(Mark)之间的行的字母转换为大写:
:'a,'b!tr [:lower:] [:upper:]
在可视化模式下,也可以使用外部程序 {filter} 过滤高亮选中的行。例如选中文本之后,点击!键,将转到屏幕底部继续输入针对选中范围'<,'>!
的命令。以下命令,将注释选中的行:
'<,'>! perl -nle 'print "\#".$_'
请注意,过滤程序将对整行进行处理,所以请使用V
命令进入的行可视化模式(Linewise visual mode)。
文本处理
使用以下命令,将按照数字顺序对当前文本进行排序。请注意,此处的外部sort命令,与Vim内部的:sort命令是不同的。
:%!sort -n
使用以下命令,将在行首增加行号:
:%!cat -n
例如在当前文件中,包含以逗号分隔的多列文本:
One,Two,Three,Four,Five arborist,apple,artichoke,ant,author branch,banana,broccoli,bee,book
使用以下Linux命令cut,可以仅保留其中的2-3列文本:
:%!cut -f2-3 -d,
Two,Three apple,artichoke banana,broccoli
生成并执行Shell命令
shell环境(比如sh和cmd),也可以作为过滤器来执行外部命令。
使用以下命令,可以将当前目录下的文件列表读取到当前文件中:
:r! ls *.html
利用替代命令,可以针对文件列表组合出需要的Shell命令。例如生成mv命令,将所有HTML文件重命名为XHTML文件:
:%s/\(.*\).html/mv & \1.xhtml
使用以下命令,则可以调用Shell来执行当前文件中的命令:
:!sh
可以看到,利用过滤器可以灵活生成并执行操作系统命令,以完成例如文件复制备份等批处理操作。
假设当前文件中包含以下Windows命令:
ping -n 1 1.1.1.1 ping -n 1 1.1.1.2 ping -n 1 1.1.1.3
使用以下命令,将用文件中ping命令的输出来替换当前文本:
%!cmd
Microsoft Windows [Version 10.0.18362.720] (c) 2019 Microsoft Corporation. All rights reserved. D:\Temp>ping -n 1 1.1.1.1 Pinging 1.1.1.1 with 32 bytes of data: Reply from 1.1.1.1: bytes=32 time=148ms TTL=54 Ping statistics for 1.1.1.1: Packets: Sent = 1, Received = 1, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 148ms, Maximum = 148ms, Average = 148ms ...
在以上命令的执行过程中可以看到,Vim会将文本行保存为临时文件,然后调用外部程序进行过滤处理,然后再用输出结果替换当前文本。
过滤器使用的临时文件,通常保存在以下位置:
- Windows:$TMP、$TEMP、c:\TMP、c:\TEMP;
- Linux:$TMPDIR、/tmp、当前目录、$HOME。
请注意,Vim将依次检查以上目录,请确保有足够的权限读写这些目录。
没有评论:
发表评论