Я хочу построить путь 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

Поскольку у меня возникли проблемы с использованием метода vim substitute() (объясняется ниже), я открыл файл, скажем 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: from:

/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 ответ1

2

Ваш код нелегок, и, как правило, 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .