我还不是 vi/vim 用户。我正在学习一种较旧的编程语言,其编译器坚持使用大写关键字。一个学习资源建议让 vi/vim 吸入一系列关键字,例如
%s/\<import\>/IMPORT/g
%s/\<module\>/MODULE/g
使用命令:所以
然后将其应用于当前缓冲区。
我正在寻找一个可以执行相同操作的 *nix 控制台实用程序。
这样的实用程序存在吗? TIA
答案1
假设您有一个包含 Vim 命令的文件,您可以使用 Vim 编辑器的选项将其应用到文件-S
:
$ cat edits
%s/\<import\>/IMPORT/g
%s/\<module\>/MODULE/g
%s/\<bumblebee\>/BUMBLEBEE/g
%s/\<please\>/PLEASE/g
%s/\<for\>/FOR/g
%s/\<over\>/OVER/g
%s/\<do\>/DO/g
%s/\<done\>/DONE/g
wq
$ cat program
module top.
import "library".
for i over <zoidberg> -> do
bumblebee i:th, please.
done
$ vim -S edits program
$ cat program
MODULE top.
IMPORT "library".
FOR i OVER <zoidberg> -> DO
BUMBLEBEE i:th, PLEASE.
DONE
wq
请注意,文件中的最后一个edits
将以与原始文件相同的文件名保存文档。
另请注意,这是一个异常从终端编辑文件的方法,并且更常见的是使用流编辑器,例如sed
(见下文)。这样做的主要问题是 Vim 不是一个非交互式编辑器,它会在执行编辑脚本之前将整个文档读入内存(这是不优雅的当不需要时)。对于您来说,必须维护编辑脚本而不是简单的关键字列表也很麻烦。
假设您有一个包含一系列小写关键字的文件,需要将其转换为大写,每行一个关键字。
一个简单的 Perl 程序会将列表转换为sed
编辑脚本:
$ cat keywords
import
module
bumblebee
please
for
over
do
done
$ perl -pe 's{.*}{s/\L\\<$&\\>/\U$&\L/g}' keywords
s/\<import\>/IMPORT/g
s/\<module\>/MODULE/g
s/\<bumblebee\>/BUMBLEBEE/g
s/\<please\>/PLEASE/g
s/\<for\>/FOR/g
s/\<over\>/OVER/g
s/\<do\>/DO/g
s/\<done\>/DONE/g
Perl 代码所做的只是获取每一行并将其插入到sed
表达式中
s/\<word\>/WORD/g
其中word
和WORD
是文件中某一行的字符串keywords
,先小写,然后大写。
然后可以将其应用于程序的源代码:
$ cat program
module top.
import "library".
for i over <zoidberg> -> do
bumblebee i:th, please.
done
$ perl -pe 's{.*}{s/\L\\<$&\\>/\U$&\L/g}' keywords | sed -f /dev/stdin program
MODULE top.
IMPORT "library".
FOR i OVER <zoidberg> -> DO
BUMBLEBEE i:th, PLEASE.
DONE
使用-f /dev/stdin
,sed
可以从 Perl 的输出中读取编辑脚本,然后将其应用到给定文件(此处为名为 的文件program
)。
请注意,这种简单的单词替换不会了解您的语言的引用规则,因此它将替换在字符串等中找到的任何可能不需要替换的关键字。
答案2
您可以类似地使用具有替换模式的 sed 文件,然后将该 sed 文件应用到您的目标文本。
以下是名为的示例 sed 文件的内容my_custom_substitutions.sed 根据上面的替换:
s/\<import\>/IMPORT/g
s/\<module\>/MODULE/g
您可以看到这些自定义替换的外观前实际上将其应用到文件中,如下所示:
sed -f my_custom_substitutions.sed targetfile.txt
要使用 sed 将这些自定义替换应用到目标文件:
sed -i -f my_custom_substitutions.sed targetfile.txt
另一种方法可以是使用tr
:
echo "lower case text" | tr '[a-z]' '[A-Z]'
如果您想在 vim 中对文件中的第 2 行执行此操作,您可以执行以下操作:
:2 ! tr '[a-z]' '[A-Z]'
如果您想将其应用于第 2 行到第 4 行等范围内的多行,您可以执行以下操作:
:2,4 ! tr '[a-z]' '[A-Z]'