По какой-то причине я не могу найти простой ответ на этот вопрос, и сейчас я немного переживаю. Как бы я вставил строку выбора после первой строки, соответствующей определенной строке, используяsed
команду. У меня есть ...
CLIENTSCRIPT="foo"
CLIENTFILE="bar"
И я хочу вставить строку после CLIENTSCRIPT=
строки, в результате чего ...
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
sed
. Это не стандартныйsed
синтаксис и не будет работать с любой другойsed
реализацией.Обратите внимание на стандартный
sed
синтаксис (как в POSIX, который поддерживается всеми соответствующимиsed
реализациями (GNU, OS / X, BSD, Solaris ...)):Или на одной строке:
(
-e
xpressions (и содержимое-f
файлов) объединяются с помощью новых строк для составленияsed
интерпретаций сценария sed ).-i
Вариант для редактирования на месте является также расширение GNU, некоторые другие реализации (например , во FreeBSD) поддержки-i ''
для этого.В качестве альтернативы для переносимости вы можете использовать
perl
вместо:Или вы можете использовать
ed
илиex
:источник
sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file
экранирует кавычку в конце первого параметра и прерывает команду.csh
илиrc
семейства -'...'
это сильные цитаты, внутри которых обратный слеш не является особенным. Единственное исключение, которое я знаю, этоfish
оболочка.sed
не POSIX-совместимый здесь. Это делает мое утверждение о том, что оно переносимо, неверно (для однострочного варианта). Я попрошу у opengroup подтверждение, действительно ли это несоответствие или неправильное толкование стандарта с моей стороны.POSIX-совместимый с помощью
s
команды:источник
sed -e '/.../s/$/\' -e 'CLI.../'
чтобы избежать проблем со строками, которые содержат последовательности байтов, не образующие допустимых символов.Команда Sed, которая работает как на MacOS (по крайней мере, на OS 10), так и на Unix (т.е. не требует gnu sed, как это делает Gilles (в настоящее время принятая)):
Это работает в bash и, возможно, в других оболочках, которые знают стиль цитаты оценки $ '\ n'. Все может быть в одной строке и работать в старых командах / POSIX sed. Если может быть несколько строк, соответствующих CLIENTSCRIPT = "foo" (или вашему аналогу), и вы хотите добавить только дополнительную строку в первый раз, вы можете переработать ее следующим образом:
(это создает цикл после кода вставки строки, который циклически перебирает остальную часть файла, никогда не возвращаясь к первой команде sed).
Вы можете заметить, что я добавил '^ *' в соответствующий шаблон в случае, если эта строка появляется в комментарии, скажем, или имеет отступ. Это не на 100% идеально, но охватывает некоторые другие ситуации, которые могут быть распространены. Отрегулируйте как требуется ...
Эти два решения также решают проблему (для общего решения по добавлению строки), что если ваша новая вставленная строка содержит неэкранированные обратные косые черты или амперсанды, они будут интерпретироваться sed и, вероятно, не получатся такими же, как это
\n
есть, например.\0
будет соответствовать первой строке. Особенно удобно, если вы добавляете строку, которая приходит из переменной, в противном случае вам пришлось бы сначала экранировать все, используя $ {var //} раньше, или другой оператор sed и т. Д.Это решение немного менее запутанно в сценариях (хотя цитирование и \ n нелегко читать), когда вы не хотите помещать текст замены для команды a в начале строки, если, скажем, в функции с отступом линий. Я воспользовался тем, что оболочка $ '\ n' вычисляется до новой строки, а не в обычных одинарных кавычках '\ n'.
Это становится достаточно длинным, хотя я думаю, что perl / даже awk могут выиграть из-за большей читабельности.
источник
s/CLIENTSCRIPT="foo"/&\
[Enter]CLIENTSCRIPT2="hello"/
. Обратная косая черта должна быть последним символом в строке (без пробела после нее), в отличие от того, как это выглядит в этом комментарии.s///
, а также тех , кто вa
иi
команды могут быть «убежали» , используя тот же метод , я описываю в моем комментарии выше.Может быть, немного поздно, чтобы опубликовать ответ на этот вопрос, но я нашел некоторые из вышеупомянутых решений несколько громоздкими.
Я попробовал простую замену строк в sed, и это сработало:
Знак & отражает соответствующую строку, а затем вы добавляете \ n и новую строку.
Как уже упоминалось, если вы хотите сделать это на месте:
Еще одна вещь. Вы можете сопоставить, используя выражение:
Надеюсь, это поможет кому-то
источник
\n
в строке замены. Plain-ваниль (POSIX)sed
ничего не понимаю\n
в строке замены, однако, так что это не будет работать на BSD или MacOS-если вы не установлены GNU СЭД каким - то образом. С помощью vanilla sed вы можете встраивать новые строки, «экранируя» их, то есть заканчивая строку обратной косой чертой, а затем нажимая [Enter] ( ссылка под заголовком для[2addr]s/BRE/replacement/flags
). Это означает, что ваша команда sed должна занимать несколько строк в терминале.Вариант awk:
источник
1;
, см. Почему «1» в awk печатает текущую строку?У меня была похожая задача, и я не смог заставить работать вышеупомянутое решение Perl.
Вот мое решение:
perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf
Объяснение:
Использует регулярное выражение для поиска строки в моем файле /etc/mysql/my.cnf, которая содержит только
[mysqld]
и заменила ее[mysqld] collation-server = utf8_unicode_ci
эффективно добавляя
collation-server = utf8_unicode_ci
строку после строки, содержащей[mysqld]
.источник
Я должен был сделать это недавно и для Mac, и для Linux, и после просмотра множества постов и опробования многих вещей, по моему собственному мнению, я так и не достиг того, чего хотел: достаточно простое, чтобы понять решение с использованием хорошо известных и стандартные команды с простыми шаблонами, один вкладыш, переносимый, расширяемый, чтобы добавить больше ограничений. Затем я попытался взглянуть на это с другой точки зрения, и тогда я понял, что могу обойтись без опции «один вкладыш», если «2-вкладыш» соответствует остальным моим критериям. В конце я придумал это решение, которое мне нравится, и оно работает как в Ubuntu, так и в Mac, которым я хотел поделиться со всеми:
В первой команде grep ищет номера строк, содержащие «foo», cut / head выбирает 1-е вхождение, а арифметическая операция увеличивает этот первый номер строки вхождения на 1, так как я хочу вставить после вхождения. Во второй команде это редактирование файла на месте, «i» для вставки: новая строка цитирования, «bar», затем еще одна новая строка. Результатом является добавление новой строки, содержащей "bar" после строки "foo". Каждая из этих 2 команд может быть расширена до более сложных операций и сопоставления.
источник