我有一个包含以下条目的文件。
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,这也是我寻找脚本解决方案的原因。
答案 0 :(得分:2)
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*')