使用VimScript词典或Awk替换字符串

时间:2016-03-21 09:10:04

标签: dictionary vim

我有一个包含以下条目的文件。

1 "A"
2 "B"
3 "C"
4 "D"
....snip....
1 2
2 4
3 4
.....snip...

现在我想知道是否可以使用vim用原始名称替换文件第二部分中的对,例如

A B
B D
C D

1 "A"可以被认为是字典条目,我需要知道如何从上面的条目中捕获大字典并使用它来进行替换。我对VimScript不是很精通,但我遇到了一个使用字典的例子。理想情况下,我希望从这些条目中得到类似的东西

let mydict = { 'A':1, 'B':2, 'C':3, 'D':4}

我的vimscript非常缺乏,允许我定义一个转换或提供替换的正确函数。非常感谢任何帮助。 最终文件看起来应该是

1 "A"
2 "B"
3 "C"
4 "D"
....snip....
A B
B D
C D
.....snip...

这些条目大约是1500,这也是我寻找脚本解决方案的原因。

2 个答案:

答案 0 :(得分:2)

如OP所评论的那样,awk解决方案也可能有所帮助:

kent$  cat f
1 "A"
2 "B"
3 "C"
4 "D"
1 2
2 4
3 4

kent$  awk '!($2~/^[0-9]+$/){a[$1]=$2;print;next}{for(i=1;i<=NF;i++)$i=a[$i]}7' f
1 "A"
2 "B"
3 "C"
4 "D"
"A" "B"
"B" "D"
"C" "D"

如果你喜欢vim,你可以在vim中执行awk one-liner。在缓冲区中:

:%!awk '\!($2~/^[0-9]+$/){a[$1]=$2;print;next}{for(i=1;i<=NF;i++)$i=a[$i]}7' 

如您所见,!已被转义。

答案 1 :(得分:1)

一旦你有了字典mydict,就可以了:

:exe '[range]s/'.join(keys(mydict),'\|').'/\=mydict[submatch(0)]/g'

您必须定义您希望操作的范围。

请注意,如果密钥可能包含\/,则需要进行一些小的更改。更糟糕的是,如果密钥不是完全独占的,您可能需要订购它们,或者找到更好的模式。如果您知道有效密钥中的任何数字,那么该模式将为\<\d\+\>,您将不需要:exe

您甚至可以使用此信息填写字典。类似的东西:

:let mydict = {}
:g/^\d\+/let mydict[matchstr(getline('.'), '^\d\+')]=matchstr(getline('.'), '^\d\+\s\+\zs.\{-}\ze\s*')
相关问题