37

Я обнаружил, что \n не работает в sed под Mac OS X. В частности, скажем, я хочу разбить слова, разделенные одним пробелом, на строки:

# input
foo bar

Я использую,

echo "foo bar" | sed 's/ /\n/'

Но результат глуп, \n не сбежал!

foonbar

После того, как я посоветовался с Google, я нашел обходной путь:

echo 'foo bar' | sed -e 's/ /\'$'\n/g'

Прочитав статью, я все еще не могу понять, что означает \'$'\n/g' . Может кто-нибудь объяснить это мне, или есть ли другой способ сделать это? Спасибо!

5 ответов5

23

Вы можете brew install gnu-sed и заменить вызовы sed на gsed .

Если вы не хотите ставить перед буквой "g" значение sed , вы можете brew install gnu-sed --with-default-names и просто вызвать sed .

(Редактировать: обновленный флаг заваривания, шляпная подсказка для Clément.)

19

Это также будет работать:

echo 'foo bar' | sed 's/ /\
/g'

echo 'foo bar' | sed $'s/ /\\\n/g'

lf=$'\n'; echo 'foo bar' | sed "s/ /\\$lf/g"

Sed OS X не интерпретирует \n в шаблоне замены, но вы можете использовать буквальный перевод строки, которому предшествует символ продолжения строки. Оболочка заменяет $'\n' буквальным переводом строки перед выполнением команды sed.

10

Обходной путь, который вы нашли, передает sed -e одну строку аргумента.

Этот аргумент заканчивается строкой в привычном формате sed s/ / /g .

Эта строка создается в двух частях, одна за другой.

Первая часть цитируется в форме '...' .

Вторая часть указана в форме $'...' .

Часть 's/ /\' удаляет одиночные кавычки, но в остальном проходит через sed, как это выглядит в командной строке. То есть обратная косая черта не съедается bash, она передается в sed.

Часть $'\n/g' получает знак доллара и удаляет одинарные кавычки, а \n преобразуется в символ новой строки.

Все вместе, аргумент становится

s/ /\newline / g

[Это было весело. Потребовалось время, чтобы развернуть это. +1 за интересный вопрос.]

6

Выражение $'...' является bash -измом, который производит ... с расширенными стандартными escape-последовательностями. Th \' перед тем, как это означает просто обратную косую черту, за которой следует конец заключенного в кавычки раздела, в результате получается строка s/ /\ . (Да, вы можете переключать кавычки в середине строки; она не заканчивается строкой.)

Стандарт sed POSIX принимает \n как часть шаблона поиска. OS X использует FreeBSD sed , которая строго соответствует POSIX; GNU, как обычно, добавляет дополнительные вещи, и тогда все пользователи Linux думают, что это своего рода "стандарт" (возможно, я был бы более впечатлен, если бы у кого-то из них был процесс стандартизации).

1

Там очень легко визуально увидеть, что происходит. Просто повторить строку!

echo 's/$/\'$'\n/g'

результаты в

s/$/\
/g

что эквивалентно s/$/\ newline /g

Если у вас не было лишних \ перед newline , оболочка интерпретировала бы newline как конец команды преждевременно.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .