Как редактировать файлы не в интерактивном режиме (например, в конвейере)?

24

Я хотел бы редактировать файлы, переданные в конвейерный ввод, используя vim неинтерактивным способом или редактировать файлы на месте (аналогично sed)

Несколько примеров с использованием sed:

$ sed -i'.bak' s/foo/test/g file   # Edit file in-place.
$ cat file | sed s/foo/test/g      # Parse file in pipeline.

Однако я мог прочитать здесь , что:

sedявляется редактором S Tream ED , а не редактором файлов. Тем не менее, люди повсюду склонны злоупотреблять им за попытку редактирования файлов. Он не редактирует файлы.

Во-вторых, некоторые параметры, такие как редактирование на месте ( -i), переносимы.

Как такая же функциональность может быть достигнута в vim?

kenorb
источник
Я думаю, вы можете выбросить второй fileиз вашей второй командной строки.
Joeytwiddle
@joeytwiddle Готово.
Кенорб

Ответы:

33

Для редактирования файла без интерактивного использования ex( viэто визуальный режим ex) вы можете использовать параметры +{command}или -c {command}параметры, которые позволяют вам выполнять команды vi после прочтения первого файла.

Это exстандартный редактор командной строки (похож на ed).

Кроме того, следует использовать vipe(редактор конвейера команд Vim), который является частью moreutilsпакета, и он позволит вам запустить ваш редактор в середине конвейера Unix и редактировать данные, передаваемые между программами.

Примеры

Простой стандартный ввод и вывод с использованием каналов может быть достигнут с помощью этого синтаксиса оболочки:

$ ex -sc'%p|q!' <(echo Example)
$ echo Example | ex -sc'%p|q!' /dev/stdin

Вот простой пример, как распечатать файл после замены:

$ ex /etc/hosts +%s/127/128/ge -sc'%p|q!'

Еще примеры для редактирования файлов на месте:

$ ex +'%s/127/128/g' -cswq file
$ ex -sc '%s/olddomain\.com/newdomain.com/g|x' file
$ printf '%s\n' 'g/olddomain\.com/s//newdomain.com/g' w q | ex -s file
$ ex -s "$file" <<< $'g/old/s//new/g\nw\nq'
$ ex -sc 'argdo %s/old/new/ge|x' ./**
$ find . -type f -exec ex -sc '%s/old/new/g|x' {} \;

Вы также можете использовать -s {scriptin}так, чтобы команды загружались из файла, например:

$ printf "%s\n" '%s/foo/test/ge' 'wq' > cmds.vim
$ vim -s cmds.vim -es file

или используя перенаправление ввода / вывода:

$ vim file < cmds.vim

Чтобы отредактировать один файл и сохранить изменения в другом, проверьте следующие примеры:

$ ex +%s/127/128/g -sc'wq! new_file' /etc/hosts
$ cat /etc/hosts /etc/fstab | vim - -es '+:%s/foo/test/g' '+:wq! file3'

Более практичные примеры.

Реальный живой пример из спецификации RPM :

vim -E -s Makefile <<-EOF
   :%substitute/CFLAGS = -g$/CFLAGS =-fPIC -DPIC -g/
   :%substitute/CFLAGS =$/CFLAGS =-fPIC -DPIC/
   :%substitute/ADAFLAGS =$/ADAFLAGS =-fPIC -DPIC/
   :update
   :quit
EOF

Извлечение HTML-тегов :

ex -s +'bufdo!/<div.*id=.the_div_id/norm nvatdggdG"2p' +'bufdo!%p' -cqa! *.html

Удаление тегов XML :

ex -s +'%s/<[^>].\{-}>//ge' +%p +q! file.txt

Извлеките тег стиля из заголовка и напечатайте проанализированный вывод:

curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin

Разобрать HTML с несколькими сложными правилами:

ex -V1 $PAGE <<-EOF
  " Correcting missing protocol, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,'//,'http://,ge
  %s,"//,"http://,ge
  " Correcting relative paths, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,[^,]\zs'/\ze[^>],'http://www.example.com/,ge
  %s,[^,]\zs"/\ze[^>],"http://www.example.com/,ge
  " Remove the margin on the left of the main block. "
  %s/id="doc_container"/id="doc_container" style="min-width:0px;margin-left : 0px;"/g
  %s/<div class="outer_page/<div style="margin: 0px;" class="outer_page/g
  " Remove useless html elements. "
  /<div.*id="global_header"/norm nvatd
  wq " Update changes and quit.
EOF

Еще больше примеров:


Смотрите также:


kenorb
источник
5
Это UUOC ; просто используйте vim '+:0,$s/foo/test/g' '+:wq! file2' file1вместо этого.
дверная ручка
2
Обратите внимание , что по крайней мере некоторые из этих примеров не являются POSIX-совместимыми, например, bufdo. Несмотря на то, что Vim - это то, что установлено практически везде, стоит знать, что вы можете создавать сценарии редактирования файлов, используя только POSIX-совместимые функцииex .
Уайлдкарт
Этот вопрос и ответ - то, что сначала вдохновило меня изучить exи действительно изучить это. Спасибо. Некоторое дальнейшее прочтение на эту тему (полное раскрытие: я написал это;) таково: поменять местами каждые четыре строкиex и использовать -cопцию . Вы можете добавить их в свой список ссылок внизу, если хотите. :)
Wildcard