Вставить строку после первого совпадения с помощью sed

по какой-то причине я не могу найти прямой ответ на этот вопрос, и в данный момент я немного хруст времени. Как я могу вставить строку выбора текста после первой строки, соответствующей определенной строке, используя . У меня есть...

CLIENTSCRIPT="foo"
CLIENTFILE="bar"

и я хочу вставить строку после CLIENTSCRIPT= строка в результате ...

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"

6 ответов


попробуйте сделать это с помощью GNU sed:

sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

если вы хотите заменить на месте используйте

sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

выход

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"

Doc

  • посмотреть sed doc поиск \a (добавление)

обратите внимание на стандарт sed синтаксис (как в POSIX, поэтому поддерживается всеми соответствующими sed реализации вокруг (GNU, OS / X, BSD, Solaris...)):

sed '/CLIENTSCRIPT=/a\
CLIENTSCRIPT2="hello"' file

или на одну строку:

sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file

(-expressions (и содержание -files) соединяются с новыми строками, чтобы составить сценарий sed sed интерпретирует).

на -i опция для редактирования на месте также является расширением GNU, некоторые другие реализации (например, FreeBSD) поддерживают -i '' для этого.

кроме того, для мобильности, вы можете использовать perl вместо:

perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file

или вы можете использовать ed или ex:

printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file

совместимый с POSIX, используя :

sed '/CLIENTSCRIPT="foo"/s/.*/&\
CLIENTSCRIPT2="hello"/' file

команда Sed, которая работает на MacOS (по крайней мере, OS 10) и Unix (т. е. не требует gnu sed, как это делает Жиль (в настоящее время принято):

sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file

это работает в bash и, возможно,других оболочках, которые знают стиль оценки $ '\n'. Все может быть на одной линии и работать в старые команды / POSIX sed. Если может быть несколько строк, соответствующих CLIENTSCRIPT= " foo "(или вашему эквиваленту), и вы хотите добавить только дополнительную строку в первый раз, вы можете переработать ее как следует:

sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file

(это создает цикл после кода вставки строки, который просто циклически проходит через остальную часть файла, никогда не возвращаясь к первой команде sed снова).

вы можете заметить, что я добавил "^ * " к соответствующему шаблону, если эта строка появляется в комментарии, скажем,или отступ. Его не 100% идеально, но охватывает некоторые другие ситуации, вероятно, будет общим. Отрегулируйте по мере необходимости...

эти два решения также обойти проблему (для общее решение для добавления строки) , что если ваша новая вставленная строка содержит неэскапированные обратные косые черты или амперсанды, они будут интерпретироваться sed и, вероятно, не выйдут одинаковыми, как и \n - это - например. будет совпадать первая строка. Особенно удобно, если вы добавляете строку, которая исходит из переменной, где в противном случае вам пришлось бы сначала избегать всего, используя ${var//} раньше или другой оператор sed и т. д.

это решение немного менее грязно в сценариях (что цитирование и \n нелегко читать), когда вы не хотите помещать текст замены для команды a в начале строки, если, скажем, в функции с отступами. Я воспользовался тем, что $ '\n 'оценивается в новую строку оболочкой, а не в регулярных "\n " одинарных кавычках.

его становится достаточно долго, хотя я думаю, что perl / даже awk может выиграть из-за того, что более читаем.


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

вот мое решение:

perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf

объяснение:

использует регулярное выражение для поиска строки в файле /etc/mysql в/мой.cnf файл, который содержал только [mysqld] и заменить

[mysqld] collation-server = utf8_unicode_ci

эффективно добавлять collation-server = utf8_unicode_ci строке после строки, содержащей [mysqld].


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

Скрипт Скачать: kinglazy-autoinsert.sh

использование:

kinglazy-autoinsert.sh (list_file) (pattern_file)

объяснение параметров:

list_file = это файл, который содержит абсолютный путь к списку файлов, которые вы хотите изменить

pattern_file = это файл, в котором вы указываете шаблон (в первом столбце), под которым вы хотите добавить новый текст. Новый текст под рисунком указано во втором столбце. И это все!

этот скрипт экономит время и помогает вам сделать работу с наименьшими усилиями.

Зависимости: Нет