Я считаю, что \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'
значит. Может кто-нибудь объяснить это мне, или есть ли другой способ сделать это? Благодарность!
echo "foo bar" | tr ' ' '\n'
\n
.Ответы:
Вы можете
brew install gnu-sed
и заменить вызовыsed
сgsed
.Если вы не хотите ставить перед «g»
sed
, вы можетеbrew install gnu-sed --with-default-names
просто позвонитьsed
.(Редактировать: обновленный флаг заваривания, шляпная подсказка для Clément.)
источник
--with-default-names
и нет--default-names
. Тем не менее, эта опция не работала на моей установке, поэтому мне пришлось вставитьalias gsed=sed
в~/.profile
нее, чтобы она работала.sed
в OS X ведет себя так, как она делает, и делает неправильное предположение, котороеgnu-sed
является более правильным. Не будьте наркоманом GNU и придерживайтесь стандартов POSIX, чтобы избежать проблем в долгосрочной перспективе.Это также будет работать:
echo 'foo bar' | sed $'s/ /\\\n/g'
lf=$'\n'; echo 'foo bar' | sed "s/ /\\$lf/g"
OS X sed не интерпретирует
\n
шаблон замены, но вы можете использовать буквальный перевод строки, которому предшествует символ продолжения строки. Оболочка заменяется$'\n'
буквальным переводом строки перед выполнением команды sed.источник
sed $'s/ /\\\n/g'
работает, а нетsed $'s/\\\n/ /g'
?sed
даже в linux / unix для удаления новых строк, потому что их анализируют / разбивают на каждой новой строке. Если вы запустите это в linux / unix, он тоже ничего не сделает:echo -e 'foo\nbar' | sed 's/\n//'
Обходной путь, который вы нашли, передает строку с одним аргументом
sed -e
.Этот аргумент заканчивается строкой в привычном
s/ / /g
формате sed .Эта строка создается в двух частях, одна за другой.
Первая часть цитируется в
'...'
форме.Вторая часть цитируется по
$'...'
форме.'s/ /\'
Часть получает одинарные кавычки содранных, но в противном случае проходит через к СЭДУ так же , как это выглядит в командной строке. То есть обратная косая черта не съедается bash, она передается в sed.$'\n/g'
Часть получает знак доллара и одинарные кавычки содранных, и\n
преобразуется в символ новой строки.Все вместе, аргумент становится
с / / \ newline/ г
[Это было весело. Потребовалось время, чтобы развернуть это. +1 за интересный вопрос.]
источник
Выражение
$'...'
являетсяbash
-ism, который производит...
с расширенными стандартными escape-последовательностями. Th ,\'
прежде чем это просто означает обратную косую черту , за которой следует в конце цитируемого раздела, результирующая строкаs/ /\
. (Да, вы можете переключать кавычки в середине строки; она не заканчивается строкой.)Стандарт POSIX
sed
принимает только\n
как часть шаблона поиска. OS X использует FreeBSDsed
, которая строго соответствует POSIX; GNU, как обычно, добавляет дополнительные вещи, и тогда все пользователи Linux думают, что это своего рода «стандарт» (возможно, я был бы более впечатлен, если бы у кого-то из них был процесс стандартизации).источник
$'...'
часть. Но ... что этоs/ /\
? Что вы имеете в видуswitch quoting
?'...'
является одним из видов цитирования оболочки;$'...'
Другой. Там же"..."
и\x
процитировать один символ. Вы можете объединить их в одно слово, что и делается, переключаясь с обычной''
строки на$''
строку для перевода\n
. В остальном, это сборкаsed
команды (s/text/replacement/flags
). В этом случае команда запускается, включая обратную косую черту в конце, чтобы защитить буквальный символ новой строки, который$'\n/g'
добавляется. Результатом является замена всех/g
пробелов ( флагов) на новые строки.Там очень легко визуально увидеть, что происходит. Просто повторить строку!
результаты в
что эквивалентно
s/$/\
newline/g
Если у вас не было лишнего
\
доnewline
, оболочкаnewline
преждевременно интерпретирует конец команды.источник