![VIM 替换环境路径以获取包含路径](https://linux22.com/image/1430649/VIM%20%E6%9B%BF%E6%8D%A2%E7%8E%AF%E5%A2%83%E8%B7%AF%E5%BE%84%E4%BB%A5%E8%8E%B7%E5%8F%96%E5%8C%85%E5%90%AB%E8%B7%AF%E5%BE%84.png)
我想include
从 上的环境变量构建路径vim
。我只想保留/share/bin
此变量上以 结尾的实例,并将它们更改为include
。我想在 上执行此操作.vimrc
,因此我使用了该vim substitute()
函数。
作为测试,我将使用这个变量:
export TEST=/afs/test/share/bin:/afs/test2/share/bin:/afs/test/bin:/afs/test3/share/bin:/cvmfs/x86_64-slc6-gcc47-opt/share:/cvmfs/x86_64-slc6-gcc47-opt/bin
此示例的期望结果是:
TEST=/afs/test/include /afs/test2/include /afs/test3/include
在尝试实现此结果时,我遇到了以下两个问题:
问题1
由于我在使用 vimsubstitute()
方法(如下所述)时遇到了麻烦,我打开了一个文件,比如说lala
,包含来自环境变量的相同文本$TEST
:
/afs/test/share/bin:/afs/test2/share/bin:/afs/test/bin:/afs/test3/share/bin:/cvmfs/x86_64-slc6-gcc47-opt/share:/cvmfs/x86_64-slc6-gcc47-opt/bin
并使用命令s/share\/bin:/include /g
获取:
/afs/test/include /afs/test2/include /afs/test/bin:/afs/test3/include /cvmfs/x86_64-slc6-gcc47-opt/share:/cvmfs/x86_64-slc6-gcc47-opt/bin
之后,我使用了命令%s#\(/.*include\)\(.*\)#\1#g
,结果:
/afs/test/include /afs/test2/include /afs/test/bin:/afs/test3/include
但是当我在 vim 上这样做时
:echo substitute(substitute($TEST,"share/bin:","include ","g"),"\(/.*include\)\(.*\)","\1","g")
我得到:
/afs/test/include /afs/test2/include /afs/test/bin:/afs/test3/include /cvmfs/x86_64-slc6-gcc47-opt/share:/cvmfs/x86_64-slc6-gcc47-opt/bin
因此,我的第一个问题是:
为什么使用时不会substitute()
给出相同的结果substitute
?
问题2
最后,我想删除所有类似于/afs/test/bin:
以下内容的实例:
/afs/test/include /afs/test2/include /afs/test/bin:/afs/test3/include
,也就是说,没有包含它。我试图:
%s#\(/.\{-}include\)\@<=\(/| \)\{-}.\{-}:# #
但它匹配/afs/test2/include /afs/test/bin:
并给出结果:
/afs/test/include /afs/test3/include
我怎样才能删除那些没有 /share/bin 的文本实例?
答案1
您的代码不容易理解,并且通常substitute()
应该表现得像:s
,所以我无法告诉您确切的问题。但是,您的整个方法仅依赖于文本替换,这使得它变得非常复杂。从版本 7 开始,Vim 就有(受 Python 启发的)函数来处理列表,这就是我在这里要使用的。我一步一步向您展示:
" Setup
let $TEST='/afs/test/share/bin:/afs/test2/share/bin:/afs/test/bin:/afs/test3/share/bin:/cvmfs/x86_64-slc6-gcc47-opt/share:/cvmfs/x86_64-slc6-gcc47-opt/bin'
" Turn into List.
let dirs = split($TEST, ':')
" Remove unwanted dirs, then substitute the rest.
call filter(dirs, 'v:val =~# "/share/bin$"')
call map(dirs, 'substitute(v:val, "/share/bin$", "/include", "")')
" Combine back into String.
let result = join(dirs, ' ')
echo result
输出:
/afs/test/include /afs/test2/include /afs/test3/include