Як редагувати файли неінтерактивно (наприклад, на конвеєрі)?


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 itor , а не редактор файлів. Тим не менш, люди скрізь схильні зловживати цим для спроб редагування файлів. Він не редагує файли.

По-друге, деякі параметри, такі як редагування на місці ( -i), є портативними.

Як однакової функціональності можна досягти в vim?


Я думаю, ти можеш скинути друге fileз другого командного рядка.
joeytwiddle

@joeytwiddle Готово.
kenorb

Відповіді:


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

Ще більше прикладів:


Дивись також:



5
Це УУПЦ ; просто використовувати vim '+:0,$s/foo/test/g' '+:wq! file2' file1замість цього.
Doorknob

2
Зауважте, що принаймні деякі з цих прикладів, наприклад, не сумісні з POSIX bufdo. Навіть незважаючи на те, що Vim встановлюється практично скрізь, варто знати, що ви можете редагувати файли скриптів, використовуючи лише сумісні з POSIX функціїex .
Wildcard

Це запитання та відповідь - це те, що спочатку надихнуло мене вивчити exта по-справжньому вивчити це. Дякую. Деякі подальші читання з цього приводу (повне розкриття: я написав це;): повернення кожні чотири рядкиex та використання -cпараметра . Ви можете додати їх у свій список посилань внизу, якщо хочете. :)
Wildcard
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.