Как вставить новую строку перед шаблоном в строке?
Например, это вставит новую строку за шаблоном регулярных выражений.
sed 's/regex/&\n/g'
Как я могу сделать то же самое, но перед шаблоном?
Учитывая этот пример входного файла, шаблон для сопоставления является номер телефона.
some text (012)345-6789
Должен стать
some text
(012)345-6789
sed '/regex/G'
Ответы:
Это работает в
bash
иzsh
, протестировано на Linux и OS X:В общем случае для
$
последующего строкового литерала в одинарных кавычкахbash
выполняется подстановка обратной косой черты в стиле C, например$'\t'
, перевод на литеральную вкладку. Кроме того, sed хочет, чтобы ваш литерал новой строки был экранирован с помощью обратной косой черты, отсюда и\
ранее$
. И, наконец, сам знак доллара не должен заключаться в кавычки, чтобы он интерпретировался оболочкой, поэтому мы закрываем кавычку перед$
и затем снова открываем ее.Изменить : как предложено в комментариях @ mklement0, это также работает:
Здесь происходит следующее: вся команда sed теперь является строкой в стиле C, что означает, что обратный слеш, который sed должен быть размещен до того, как литерал новой строки теперь должен быть экранирован с помощью другого обратного слеша. Хотя это и более читабельно, в этом случае вы не сможете выполнять подстановку строк оболочки (без того, чтобы снова сделать это уродливым).
источник
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
. Обратите внимание на две одинарные кавычки после \ n. Первый закрывает$
раздел " ", так что оставшаяся часть строки не затрагивается им. Без этих кавычек, \ 2 был проигнорирован.sed $'s/regexp/\\\n/g'
которая улучшает читабельность - единственное предостережение в том, что вам необходимо удвоить все буквенные\
символы.Некоторые другие ответы не работали для моей версии sed. Переключение позиций
&
и\n
сделал работу.Изменить: Это не похоже на OS X, если вы не установите
gnu-sed
.источник
brew install gnu-sed
затемgsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
В sed вы не можете легко добавлять новые строки в выходной поток. Вам нужно использовать строку продолжения, что неудобно, но работает:
Пример:
Смотрите здесь для деталей. Если вы хотите что-то немного менее неловкое, вы можете попробовать использовать
perl -pe
с группами совпадений вместо sed:$1
относится к первой сопоставленной группе в регулярном выражении, где группы заключены в скобки.источник
perl -pi -e 's/(.*)/\n$1/' foo
s
вызова функции (в отличие от реализации Sed GNU , которая это делает) , Приведенный выше ответ работает с обеими реализациями; обзор всех отличий см. здесь .На моем Mac следующее вставляет один 'n' вместо новой строки:
Это заменяет на новую строку:
источник
sed -i '' -e ...
и у меня были проблемы с^M
записью каретки M (ctrl + m) в файл. В итоге я использовал Perl с теми же параметрами.\n
).echo...
символа и новой строки), что я просто сделал это в vim.sed "s/regexp/`echo`/g"
- это даст один LF вместо LF-CR`echo`
приведет к пустой строке , потому что подстановки команд неизменно обрезают все завершающие символы новой строки. Невозможно использовать подстановку команд для прямой вставки одной новой строки (и вставка\n\r
- то есть дополнительный CR - ужасная идея).источник
$'\n'
полагается на оболочку для генерации новой строки. Такие решения не могут быть портативными. Этот. Конечно, это также дубликат второго примера в ответе tgamblin от 2009 года.В этом случае я не использую sed. Я использую tr.
Это берет запятую и заменяет ее возвратом каретки.
источник
cat Somefile | tr ',' '\n'
YMMVВы можете использовать perl one-liners так же, как и с sed, с преимуществом полной поддержки регулярных выражений perl (что гораздо мощнее, чем то, что вы получаете с sed). На * nix платформах также очень мало изменений - perl обычно perl. Таким образом, вы можете перестать беспокоиться о том, как заставить версию вашей конкретной системы sed делать то, что вы хотите.
В этом случае вы можете сделать
-pe
помещает perl в цикл «выполнить и напечатать», очень похожий на обычный режим работы sed.'
цитирует все остальное, чтобы оболочка не мешала()
окружающее регулярное выражение является оператором группировки.$1
на правой стороне замены печатает то, что было найдено в этих скобках.Наконец,
\n
это новая строка.Независимо от того, используете ли вы скобки в качестве оператора группировки, вы должны избегать любых скобок, которые вы пытаетесь сопоставить. Таким образом, регулярное выражение в соответствии с шаблоном, который вы перечислили выше, будет что-то вроде
\(
или\)
соответствует буквальному пареню и\d
соответствует цифре.Лучше:
Я полагаю, вы можете выяснить, что делают числа в фигурных скобках.
Кроме того, вы можете использовать разделители, отличные от / для вашего регулярного выражения. Так что если вам нужно соответствовать / вам не нужно избегать его. Любое из нижеприведенного равнозначно регулярному выражению в начале моего ответа. Теоретически вы можете заменить любой символ на стандартное.
Пара заключительных мыслей.
использование
-ne
вместо-pe
действует аналогично, но в конце автоматически не печатается. Это может быть удобно, если вы хотите печатать самостоятельно. Например, вот что такое grep (m/foobar/
как регулярное выражение):Если вам трудно работать с новыми строками, и вы хотите, чтобы это было волшебным образом для вас, добавьте
-l
. Не полезно для ОП, который работал с новыми строками.Дополнительный совет - если у вас установлен пакет pcre, он поставляется вместе с
pcregrep
регулярными регулярными выражениями, совместимыми с perl.источник
Хм, только что вышедшие из новой строки, похоже, работают в более поздних версиях
sed
(у меня GNU sed 4.2.1),источник
отлично работал на Эль Captitan при
()
поддержкеисточник
Чтобы вставить новую строку в выходной поток в Linux, я использовал:
Где
file1
был:Перед заменой сид на месте, и:
После седа на месте замены. Пожалуйста, обратите внимание на использование
\\\n
. Если у шаблонов есть"
внутренняя часть, избегайте использования\"
.источник
sed
вставляет\n
вместо LF, потому что он получает\\n
параметр из оболочки. --- Этот код работает:sed -i "s/def/abc\ndef/" file1
. ---GNU sed version 4.2.1
,GNU bash, version 4.1.2(1) / 4.2.25(1)
(CentOS выпуск 6.4 / Ubuntu 12.04.3).В sed вы можете ссылаться на группы в вашем шаблоне с помощью "\ 1", "\ 2", ...., так что если вы ищете шаблон "PATTERN", и вы хотите вставить перед ним "BEFORE" Вы можете использовать, без побега
т.е.
источник
Вы также можете сделать это с помощью awk, используя
-v
шаблон:Это проверяет, содержит ли строка данный шаблон. Если это так, он добавляет новую строку в начало.
Смотрите базовый пример:
Обратите внимание, что это повлияет на все шаблоны в строке:
источник
1
используется в Awk для краткости{print $0}
. Причина в том, что любое условие, которое оценивается как True, запускает действие Awk по умолчанию, которое состоит в печати текущей записи.Это работает в MAC для меня
Дону ли его идеальный ...
источник
Прочитав все ответы на этот вопрос, мне все еще потребовалось много попыток получить правильный синтаксис для следующего примера сценария:
Скрипт добавляет новую
\n
строку, за которой следует другая строка текста, в конец файла с помощью однойsed
команды.источник
\ 0 - это ноль, поэтому ваше выражение заменяется на ноль (ничего), а затем ...
\ n - это новая строка
Некоторые версии Unix не работают, но я думаю, что это решение вашей проблемы.
источник
В vi в Red Hat мне удалось вставить возврат каретки, используя только символ \ r. Я считаю, что это внутренне выполняет 'ex' вместо 'sed', но это похоже, и vi может быть другим способом массового редактирования, такого как исправления кода. Например. Я окружаю поисковый запрос выражением if, которое настаивает на возврате каретки после фигурных скобок:
Обратите внимание, что я также вставил несколько вкладок, чтобы все выровнялось лучше.
источник