Сед, как заменить одну строку на 2 строки? - PullRequest
9 голосов
/ 17 августа 2011

Я пытаюсь заменить 1 строку на 2 строки, используя sed в debian, и вот что я придумал:

 sed -i 's/You are good/You are good\n You are the best/g' /output.txt

Однако, когда я делал это, sed продолжал жаловаться, говоря неизвестную опцию `s '.

Кто-нибудь может помочь?

Спасибо!

Ответы [ 3 ]

10 голосов
/ 17 августа 2011

Попробуйте, если вы в bash:

sed -i.bak $'s/You are good/You are good\\\nYou are the best/g' /output.txt

Странно, а? Но похоже на работу. Возможно, sed не может правильно обработать символ новой строки, поэтому его необходимо экранировать с помощью другой обратной косой черты, поэтому \\, которая станет единым \ перед переходом к sed.

Также обратите внимание, что вы не передавали расширение -i.


Редактировать

Только что нашел другое решение. Поскольку при переходе к sed необходимо экранировать символ новой строки (иначе он считает, что это терминатор команды), вы можете использовать одинарные кавычки и возврат, просто вставьте обратную косую черту перед вводом новой строки.

$ echo test | sed 's/test/line\
> line'
line
line
7 голосов
/ 17 августа 2011

Или вместо поиска и замены (команда s), поиск и добавление (команда a)

sed -i '/Your are good/a You are the best' filename
1 голос
/ 01 сентября 2015

EDIT:

Вероятно, мой любимый метод в настоящее время - использовать специальный символ вместо '\ n'. Правила цитирования становятся такой головной болью, когда вы передаете строку. Но если вы упакуете свою строку, скажем, | вместо \n и _ вместо , тогда у вас будет действительно переносимое представление, которое вы можете передать функциям и т. Д.

Вот пример:

whatAmI=$( printf "Wow oh wow\nYou are good\n"| \
             sed -e 's#\(You are \)\(good\)#\1\2|\1the best#g' | \
             tr '\n' '|' | tr ' ' '_' )

Результат:

Wow_oh_wow | You_are_good | You_are_the_best |

Чтобы "распаковать" вашу сжатую строку, просто пропустите ее через тот же tr, но с обратным порядком.

1025 * т.е. *

echo "$whatAmI" | tr '|' '\n' | tr '_' ' '

Результат

Ух ты, вау
Вы хороши
Ты лучший


В дополнение к вышеприведенным стратегиям (используя appen - /a и ограничивая \\\n) вы также можете сделать это:

sed -i 's/You are good/You are good'"\n"' You are the best/g' /output.txt

В каком-то смысле я предпочитаю решение Гленна Джекмана, так как оно более справедливо для намерения.

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

whatYouAre="okay"
sed -i 's/You are good/You are good'"\n"' You are '"${whatYouAre}"'/g' /output.txt

(Примечание: одинарные кавычки также работают для \n, но не для передачи в переменные, так как это требует интерпретации.)

...