2015-01-06 2 views
0

Я пытаюсь использовать Vim с опцией -s, чтобы запустить скрипт, который заменяет несколько строк в файле, как это (text.txt):ВИМ скрипт оставляет символы стандартного ввода

test1 
ab 
ac 
ae 
test2 
sd 

файл сценария как это (сценарий):

:silent %s/test1\zs\_.\+\zetest2/\=substitute(submatch(0), '\n\(\w\)', '\n#\1', 'g')/g 
:wq 

Он комментирует строки между test1 и test2. Это то, что я хочу. То, что я не хочу, но выводится до и после подсказки. Я запустить его и получить:

[email protected]: ~/vimtest$ vim -s script text.txt 
^[[?1;[email protected]: ~/vimtest$ 1;2c 

Так это ^[[?1;2c плохая новость уже, но 1;2c находится на входе, как будто я уже напечатал его. Если я попал в него, это даст мне ошибку bash. Поэтому я должен удалить эти символы каждый раз, когда используется сценарий. Есть идеи?

ответ

2

Похоже vim (или какой-то запуска ВИМ сценария) является пытаясь выяснить, какой тип терминала вы используете. ^[[?1;2c с последними символами, оставшимися во входном буфере, почти наверняка является частью ответа вашего эмулятора терминала на запрос DA (Device Attributes). Вы можете увидеть это сами, набрав в Баш:

printf '\033[c' 

или, чтобы увидеть полный возврат, пауза немного:

printf '\033[c'; sleep 0.1; echo 

Отклик \033[?1;2c означает «Я VT100 с Advanced Video Option . », что и есть xterm и многие другие консольные программы. (Сама консоль Linux отвечает \033[?6c, что означает «Я VT102.«)

Причина, по которой только 1;2c остается во входной консоли буфера, кстати, является то, что исходный код побег \033[? был проигнорирован, когда он был прочитан. readline библиотека будет игнорировать его, не повторяя его, в то время как нормальный консоли вход будет эхом, а затем проигнорирует его, поэтому команды двух команд оболочки выше отличаются.

Я не могу воспроизвести эту проблему с моей установкой vim, поэтому я даже не знаю, с чего начать. попытайтесь выяснить, поможет ли отключить все файлы автозагрузки:

vim -u NONE -s script text.txt 

Если это помогает, начните отключать установленные расширения один за другим, пока не найдете тот, который вызывает проблему.

+0

Спасибо! Опция '-u NONE' была разработана, и виновником был' синтаксис on' в строке '~/.vimrc' – lonelyelk

+1

@lonelyelk: так что где-то в ваших файлах синтаксиса (предположительно в инициализации) есть некоторый скрипт vim с ошибкой. Если вы хотите начать копать, посмотрите файлы в каталоге '$ VIMRUNTIME/syntax', начиная с' $ VIMRUNTIME/syntax/syntax.vim' и '$ VIMRUNTIME/syntax/synload.vim'. Удачи. – rici

1
:%s/test1\zs\_.\+\ze\ntest2/\=substitute(submatch(0), '\n', '\n#', 'g')/g 
:wq 

Здесь протестировано, оно изменило входной файл в требуемом порядке.

Некоторые изменения, сделанные на основе вашей команды:

  • добавить \n после \ze
  • в заменителя() функции мы можем только обрабатывать \n, нам не нужно, чтобы захватить слово после \n
1

Я заметил, что вы отметили вопрос bash, поэтому я подумал, что решение оболочки тоже должно быть принято.

awk '/test1/{p=1;print;next}/test2/{p=0;print;next}{$0=(p?"#":"")$0}7' file 

Этот awk oneliner должен сделать это за вас. vim - очень мощный редактор, я люблю vim. Но если вы хотите сделать автоматическое преобразование, я предпочитаю сценарий или инструмент для обработки текста. В окне Linux вы всегда можете найти его. Легче тестировать и отлаживать.

Тест с входом:

kent$ cat f 
test1 
ab 
ac 
ae 
test2 
sd 

kent$ awk '/test1/{p=1;print;next}/test2/{p=0;print;next}{$0=(p?"#":"")$0}7' f 
test1 
#ab 
#ac 
#ae 
test2 
sd 

Если вы хотите сохранить текст обратно в файл, вы можете:

awk '...' file > tmp.file && mv tmp.file file 
+0

Благодарим вас за это предложение. Это менее удобно для sudo. Все это произошло из-за необходимости прокомментировать, а затем снова включить фрагменты файла/etc/hosts. Как ежедневно. – lonelyelk

Смежные вопросы