Как я могу использовать sed или ex для замены блока (многострочный код) новым блоком текста (кода)?

Я должен заменить большой блок текста (код сценария оболочки) в файле с другим блоком текста.

Я впечатлен тем, как использовать sed для замены многострочной строки? ответил антак и многострочная замена, на которые ответил Брюс Эдигер

Но у меня есть некоторые проблемы с их использованием.

  1. Антак уже упоминал в своем ответе, что потоковый файл целиком ( 1h;2,$H;$!d;g; ) в буфер не рекомендуется для больших файлов, поскольку он перегружает память.

  2. Я знаю, что sed можно использовать с функцией блока, чтобы сохранить текст вне блока без изменений. Я хочу использовать эту функцию. Но если я использую,

     sed -i '/marker1/,/marker2/s/.*/new text (code)/' filename 

он будет вставлять новый текст (код) несколько раз для каждого потока. Следовательно, я должен сделать визуальный блок одним потоком, используя что-то похожее на то, что было предложено antak раньше, но для блока (а не для всего файла).

  1. Как упоминалось Брюсом Эдигером, добавьте функцию ex которая начинается с конца . (точка) можно попробовать, но мой новый текст (код) содержит строки, начинающиеся с точки, которые можно рассматривать как точку синтаксиса append. Как я могу использовать его в этой ситуации?

  2. ex 's dd ' количество строк 'может удалять несколько строк, но если у меня есть блок между / marker1 / и / marker2 / с числом строк, не фиксированным (изменяющимся), следует заменить новым текстом (кодом), как сделать это ?

3 Solutions collect form web for “Как я могу использовать sed или ex для замены блока (многострочный код) новым блоком текста (кода)?”

Использование GNU sed

Для замены строк, начинающихся с строки, соответствующей 3 и продолжения строки, соответствующей 5 с помощью New Code :

 $ seq 8 | sed '/3/,/5/{/5/ s/.*/New Code/; t; d}' 1 2 New Code 6 7 8 

Для строк в диапазоне /3/,/5/ мы проверяем, соответствует ли строка 5 (что означает, что это последняя строка в группе), и если да, то мы делаем замену, чтобы вставить New Code . Если подстановка была сделана, команда t подскажет sed перейти к концу команд (в этом случае будет напечатан New Code ). Если нет, команда d сообщает sed удалить строку.

Все остальные строки печатаются нормально.

Чтобы изменить файл на месте, можно использовать опцию -i :

 sed -i.bak '/3/,/5/{/5/ s/.*/New Code/; t; d}' file 

Использование awk

Чтобы сделать то же самое с помощью awk:

 $ seq 8 | awk '/3/,/5/{if (!f)print "New Code"; f=1; next}; 1' 1 2 New Code 6 7 8 

Команда awk обрабатывает строки в диапазоне /3/,/5/ специально. Для строк в этом диапазоне мы проверяем, является ли f нулевым (то есть if !f истинно), и если это так, мы печатаем New Code и устанавливаем f в 1, а затем пропускаем остальные команды и переходим к next строка.

Для линий вне диапазона /3/,/5/ переход не выполняется, а 1 вызывает печать строки. Более подробно, 1 является условием. Поскольку 1 не равно нулю, условие принимает значение true. Поскольку никакое действие не связано с условием, выполняется действие по умолчанию, которое должно печатать строку. Таким образом, 1 является сокращением для печати.

Чтобы изменить файл на месте, можно использовать опцию -i inplace с GNU awk 4.1 или выше:

 awk -i inplace '/3/,/5/{if (!f)print "New Code"; f=1; next} 1' file 

Я предлагаю использовать команду c hange (которая по существу является d elete в сочетании с ppend, хотя append применяется только для последней строки в диапазоне, который именно вы здесь хотите):

 sed -i '/marker1/,/marker2/c\ New text 1\ New text 2' filename 

Здесь используется синтаксис GNU sed для редактирования на месте ( -i ). Эта команда c в противном случае является стандартной и переносной. sed GNU sed :

 sed '/marker1/,/marker2/cNew text 1\ New text 2' filename 

как нестандартное расширение.

Символы новой строки и обратной косой черты должны быть экранированы (с обратной косой чертой) в заменяемом тексте.

Основываясь на приведенном выше обсуждении, я придумываю решение, используя ex

 seq 15 > test1.txt ex test1.txt << EOEX /^7/,/^9/c abcd 123 .xyz hfr4 . w! q EOEX cat test1.txt 

Вышеприведенное дает

 1 2 3 4 5 6 abcd 123 .xyz hfr4 10 11 12 13 14 15 

Спасибо g-man, чтобы сообщить мне об изменении команды и дать разъяснения о точке. Оба sed и ex используют почти аналогичный синтаксис команды change (также для команды delete, команды append и т. Д.).

  • Заменить многострочную строку в файлах
  • Как работать с несколькими командами sed в aix?
  • Как разделить строки vCards
  • Как добавить нуль (0) в пробелы в большом файле (пример файла ниже)
  • Что значит . совпадение?
  • Замените строку в файле на другую, где оба сохраняются в переменных
  • Файлы Concat 1000 в каталоге
  • Добавить во второй столбец
  • Извлечение части строк с определенным шаблоном с помощью awk, sed
  • Разбор CSV с использованием AWK или SED
  • Как найти, на каком устройстве находится файл (и использовать его в скрипте)?
  • Interesting Posts

    в чем разница между `>> / dev / stderr` (с пробелом) и`> & 2`?

    Bash для просмотра изменений файловой системы с задержкой перед выполнением сценария резервного копирования

    Вычислить разницу дат между последней измененной датой файла и СЕЙЧАС с использованием сценария оболочки

    В терминале терминологии, как мне изменить его оболочку входа?

    Как скопировать локальный файл при подключении с помощью ssh

    Содержимое домашнего каталога root в OSX

    Не удалось расшифровать раздел LUKS

    Есть ли способ отложить инициализацию драйвера на Beaglebone Black?

    Загрузка с raid'ed> дисков 2GB, btrfs, обработка раздела загрузки BIOS

    Почему ls -l показывает время и год для каждого файла?

    Использовать vimrc другого пользователя, а также папку vim

    Как перезапустить службу systemd при изменении графики?

    Как изменить выходной цвет команды ls в терминале в OS X и iTerm2?

    Какое правильное место для создания нового WINEPREFIX?

    Зашифровать сразу несколько файлов

    Linux и Unix - лучшая ОС в мире.