Ответ 1
Некоторые из других ответов не помогли моей версии sed.
Переключение позиций &
и \n
действительно работало.
sed 's/regexp/\n&/g'
Изменить: это не работает на OS X, если вы не установите gnu-sed
.
Не как вставить новую строку перед строкой. Это спрашивает, как вставить новую строку перед шаблоном внутри строки.
Например,
sed 's/regexp/&\n/g'
вставляет новую строку за шаблоном regexp.
Как я могу сделать то же самое, но перед шаблоном?
Вот пример входного файла
somevariable (012)345-6789
Должно стать
somevariable
(012)345-6789
Некоторые из других ответов не помогли моей версии sed.
Переключение позиций &
и \n
действительно работало.
sed 's/regexp/\n&/g'
Изменить: это не работает на OS X, если вы не установите gnu-sed
.
Это работает в bash
, протестированном в Linux и OS X:
sed 's/regexp/\'$'\n/g'
В общем случае для $
, за которым следует строковый литерал в одинарных кавычках bash
выполняет подстановку обратного слэша C-стиля, например. $'\t'
переводится на литеральную вкладку. Кроме того, sed хочет, чтобы ваш литерал новой строки был экранирован с обратной косой чертой, поэтому \
до $
. И, наконец, сам знак доллара не следует указывать так, чтобы он интерпретировался оболочкой, поэтому мы закрываем цитату перед $
и снова открываем ее.
Изменить. Как было предложено в комментариях @mklement0, это также работает:
sed $'s/regexp/\\\n/g'
Что происходит здесь: вся команда sed теперь является строкой C-стиля, что означает обратную косую черту, которую sed требует разместить перед тем, как новый литерал строки теперь будет экранирован с помощью другой обратной косой черты. Хотя это более читаемо, в этом случае вы не сможете выполнять замену строк оболочки (не делая это снова уродливо).
В sed вы не можете легко добавлять новые строки в выходной поток. Вам нужно использовать линию продолжения, которая неудобна, но она работает:
$ sed 's/regexp/\
&/'
Пример:
$ echo foo | sed 's/.*/\
&/'
foo
Подробнее см. здесь. Если вам нужно что-то немного неудобное, вы можете попробовать использовать perl -pe
с группами соответствия вместо sed:
$ echo foo | perl -pe 's/(.*)/\n$1/'
foo
$1
относится к первой согласованной группе в регулярном выражении, где группы находятся в круглых скобках.
На моем mac, следующий вставляет единственное 'n' вместо новой строки:
sed 's/regexp/\n&/g'
Это заменяет символом новой строки:
sed "s/regexp/\\`echo -e '\n\r'`/g"
echo one,two,three | sed 's/,/\
/g'
В этом случае я не использую sed. Я использую tr.
cat Somefile |tr ',' '\012'
Это принимает запятую и заменяет ее возвратом каретки.
Вы можете использовать perl one-liners так же, как и с sed, с преимуществом полной поддержки регулярных выражений perl (что намного мощнее, чем то, что вы получаете с sed).
Кроме того, на платформах * nix очень мало изменений - perl, как правило, perl. Поэтому вы можете перестать беспокоиться о том, как сделать вашу конкретную системную версию sed необходимой для вас.
В этом случае вы можете сделать
perl -pe 's/(regex)/\n$1/'
-pe
помещает perl в цикл "выполнить и распечатать", как и обычный нормальный режим работы.
'
цитирует все остальное, поэтому оболочка не будет мешать
()
, окружающее регулярное выражение, является оператором группировки. $1
в правой части подстановки выдает все, что было согласовано внутри этих парнеров.
Наконец, \n
является новой строкой.
Независимо от того, используете ли вы круглые скобки в качестве оператора группировки, вам нужно избегать любых круглых скобок, которые вы пытаетесь сопоставить. Таким образом, регулярное выражение, соответствующее шаблону, указанному выше, будет выглядеть как
\(\d\d\d\)\d\d\d-\d\d\d\d
\(
или \)
соответствует буквальному парсу, а \d
соответствует цифре.
лучше:
\(\d{3}\)\d{3}-\d{4}
Я полагаю, вы можете понять, что делают цифры в фигурных скобках.
Бонусный совет - если у вас установлен пакет pcre, он поставляется с pcregrep
, который использует полные perl-совместимые регулярные выражения.
Хм, только ускользнувшие новые строки, похоже, работают в более поздних версиях sed
(у меня есть GNU sed 4.2.1),
dev:~/pg/services/places> echo 'foobar' | sed -r 's/(bar)/\n\1/;'
foo
bar
Чтобы вставить новую строку для вывода потока в Linux, я использовал:
sed -i "s/def/abc\\\ndef/" file1
Где file1
было:
def
Перед заменой sed на месте и:
abc
def
После замены на месте. Обратите внимание на использование \\\n
. Если у шаблонов есть "
внутри него, бегите с помощью \"
.
в sed вы можете ссылаться на группы в вашем шаблоне с помощью "\ 1", "\ 2",.... поэтому, если шаблон, который вы ищете, является "PATTERN", и вы хотите вставить перед ним "BEFORE", вы можете использовать, без экранирования
sed 's/(PATTERN)/BEFORE\1/g'
то есть.
sed 's/\(PATTERN\)/BEFORE\1/g'
sed -e 's/regexp/\0\n/g'
\0 - это нуль, поэтому ваше выражение заменяется нулевым (ничего), а затем...
\n - это новая строка
В некоторых вариантах Unix не работает, но я думаю, что это решение по вашей проблеме.
echo "Hello" | sed -e 's/Hello/\0\ntmow/g'
Hello
tmow
echo pattern | sed -E -e $'s/^(pattern)/\\\n\\1/'
отлично работал на El Captitan с поддержкой ()
Вы также можете сделать это с помощью awk, используя -v
, чтобы предоставить шаблон:
awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
Это проверяет, содержит ли строка данный шаблон. Если это так, он добавляет новую строку в начало.
См. базовый пример:
$ cat file
hello
this is some pattern and we are going ahead
bye!
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
hello
this is some
pattern and we are going ahead
bye!
Обратите внимание, что это повлияет на все шаблоны в строке:
$ cat file
this pattern is some pattern and we are going ahead
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' d
this
pattern is some
pattern and we are going ahead
В vi на Red Hat мне удалось вставить возврат каретки, используя только символ \r. Я считаю, что это внутренне выполняется ex 'вместо' sed ', но похоже, и vi может быть другим способом делать массовые изменения, такие как исправления кода. Например. Я окружаю поисковый запрос с утверждением if, который настаивает на возврате каретки после привязок:
:.,$s/\(my_function(.*)\)/if(!skip_option){\r\t\1\r\t}/
Обратите внимание, что я также добавил, что он вставлял некоторые вкладки, чтобы улучшить соответствие элементов.
Это работает в MAC для меня
sed -i.bak -e 's/regex/xregex/g' input.txt sed -i.bak -e 's/qregex/\'$'\nregex/g' input.txt
Доно ли его идеальный...
Прочитав все ответы на этот вопрос, мне все же потребовалось много попыток получить правильный синтаксис в следующем примере script:
#!/bin/bash
# script: add_domain
# using fixed values instead of command line parameters $1, $2
# to show typical variable values in this example
ipaddr="127.0.0.1"
domain="example.com"
# no need to escape $ipaddr and $domain values if we use separate quotes.
sudo sed -i '$a \\n'"$ipaddr www.$domain $domain" /etc/hosts
script добавляет новую строку \n
, а затем другую строку текста в конец файла, используя одну команду sed
.
Поскольку sed в OS X может быть нечетким для расширенной подстановки, я использовал php для этого, так как он может быть вызван непосредственно из CLI с опцией -r
:
php -r 'str_replace("pattern", "\npattern");'
Кроме того, php может передаваться аргументам, поэтому он отлично интегрируется в расширенный script. Здесь более надежный пример с php, встроенным в bash script, который будет выполнять подстановку непосредственно в файле:
pattern=xxx
php -r '$filePath = "/home/buzut/file"; file_put_contents($hostsFilePAth, str_replace($argv[1], "\n$argv[1]", file_get_contents($filePath)));' $pattern