sed help: сопоставление и замена литерала "\n" (не перевод строки)

У меня есть файл, который содержит несколько экземпляров \ n.

Я хотел бы заменить их реальными символами новой строки, но sed не распознает \ n.

Я старался

sed -r -e 's/\n/\n/'
sed -r -e 's/\\n/\n/'
sed -r -e 's/[\n]/\n/'

и много других способов избежать этого.

способен ли sed распознавать литерал \ n? если да, то как?

Есть ли другая программа, которая может прочитать файл, интерпретируя \ n'как настоящие новые строки?

5 ответов

Решение

Можете ли вы попробовать это

sed -i 's/\\n/\n/g' input_filename
$ echo "\n" | sed -e 's/[\\][n]/hello/'

Что именно работает, зависит от вашей реализации. Это плохо определено в POSIX, поэтому вы видите все виды поведения.

Опция также нестандартная, но предполагает, что вы используете платформу, подобную BSD; но ваш скрипт не использует ни один из -rфункции, так что давайте просто уберем его. (Как бы то ни было, он меняет диалект регулярных выражений, поддерживаемый в выражении соответствия, с «базового» POSIX на «расширенные» регулярные выражения; некоторые другие варианты имеют -Eвариант, который делает то же самое. Короче говоря, такие вещи, как захват круглых и повторяющихся скобок, являются «расширенными» функциями.)

На платформах BSD, как правило, рекомендуется использовать символ новой строки с обратной косой чертой, например:

      sed 's/\\n/\
/g' file

В некоторых других системах, таких как Linux (также в зависимости от установленной версии - некоторые дистрибутивы используют GNU sed, другие предпочитают что-то более традиционное, третьи позволяют вам выбирать) вы можете использовать буквальный \n в строке замены.

Если вам нужно правильно переносимое решение, возможно, используйте Awk или (ах!) Perl.

      perl -pe 's/\\n/\n/g' file

Если у вас нет доступа к руководствам, /gфлаг говорит заменить каждое вхождение в строке; поведение по умолчанию s/// команда заменяет только первое совпадение в каждой строке.

awk кажется, справиться с этим хорошо:

echo "test \n more data" | awk '{sub(/\\n/,"**")}1'
test ** more data

Здесь вам нужно сбежать \ с помощью \\

1) sed работает 1 строка в сыну времени no \n только на 1 строке (он удаляется sed во время чтения в буфер). Вы должны использовать N,n или H, h, чтобы заполнить буфер более чем на 1 строку, и внутри появится \ n. Будьте осторожны, ^ и $ больше не конец строки, а конец строки / буфера, поэтому \ n находятся внутри. 2) \n распознается в шаблоне поиска, а не в шаблоне замены. 2 способа его использования (пример)

sed s/\(\n\)bla/\1blabla\1/
sed s/\nbla/\
blabla\
/

сначала используйте \ n уже внутри в качестве обратной ссылки (меньшая строка в шаблоне замены), во-вторых, используйте настоящую новую строку

так в основном

sed "N
$ s/\(\n\)/\1/g
"

работать (но немного бесполезно). Я представляю что s/\(\n\)\n/\1/g больше того, что вы хотите

Другие вопросы по тегам