Новые строки в sed на Mac OS X
Я нахожу это \n
не работает в sed под Mac OS X. В частности, скажем, я хочу разбить слова, разделенные одним пробелом, на строки:
# input
foo bar
Я использую,
echo "foo bar" | sed 's/ /\n/'
Но результат глупый, \n
не сбежал!
foonbar
После того, как я посоветовался с Goo gle, я нашел обходной путь:
echo 'foo bar' | sed -e 's/ /\'$'\n/g'
Прочитав статью, я все еще не могу понять, что \'$'\n/g'
средства. Может кто-нибудь объяснить это мне, или есть ли другой способ сделать это? Спасибо!
5 ответов
Вы можете brew install gnu-sed
и заменить звонки sed
с gsed
,
Если вы не хотите ставить перед "g" sed
, вы можете brew install gnu-sed --with-default-names
и просто позвони sed
,
(Редактировать: обновленный флаг заваривания, шляпная подсказка для Clément.)
Это также будет работать:
echo 'foo bar' | sed 's/ /\
/g'
echo 'foo bar' | sed $'s/ /\\\n/g'
lf=$'\n'; echo 'foo bar' | sed "s/ /\\$lf/g"
OS X Sed не интерпретирует \n
в шаблоне замены, но вы можете использовать буквальный перевод строки, которому предшествует символ продолжения строки. Оболочка заменяет $'\n'
с буквальным переводом строки перед запуском команды sed.
Обходной путь, который вы нашли, передает строку с одним аргументом sed -e
,
Этот аргумент в конечном итоге является строкой в привычном седе s/ / /g
формат.
Эта строка создается в двух частях, одна за другой.
Первая часть цитируется в '...'
форма.
Вторая часть цитируется в $'...'
форма.
's/ /\'
part удаляет одиночные кавычки, но в остальном проходит через sed, как это выглядит в командной строке. То есть обратная косая черта не съедается bash, она передается в sed.
$'\n/g'
часть получает знак доллара, а одинарные кавычки снимаются, а \n
превращается в символ новой строки.
Все вместе, аргумент становится
s / / \newline/ g
[Это было весело. Потребовалось время, чтобы развернуть это. +1 за интересный вопрос.]
Выражение $'...'
это bash
-изм, который производит ...
с расширенными стандартными escape-последовательностями. Th \'
перед тем, как это просто означает обратную косую черту, за которой следует конец секции в кавычках, полученная строка s/ /\
, (Да, вы можете переключать кавычки в середине строки; она не заканчивается строкой.)
Стандарт POSIX sed
только принимает \n
как часть шаблона поиска. OS X использует FreeBSD sed
, который строго соответствует POSIX; GNU, как обычно, добавляет дополнительные вещи, и тогда все пользователи Linux думают, что это своего рода "стандарт" (возможно, я был бы более впечатлен, если бы у кого-то из них был процесс стандартизации).
Там очень легко визуально увидеть, что происходит. Просто повторить строку!
echo 's/$/\'$'\n/g'
результаты в
s/$/\
/g
что эквивалентно s/$/\
новая линия/g
Если у вас не было лишних \
перед newline
оболочка будет интерпретировать newline
как конец команды преждевременно.
Этот обходной путь работает на Mac, и скрипт может быть выполнен также в Linux.
NL="\n"
if [[ $uname -eq "Darwin" ]]; then
NL=$'\\\n'
fi
echo 'foo bar' | sed -e "s| |${NL}|"
Немного более компактная форма ответа @max-zerbini:
[[ $(uname) -eq "Darwin" ]] && NL=$'\\\n' || NL="\n"
echo 'foo bar' | sed -e "s| |${NL}|"