Заменить запятую на новую строку в sed на MacOS?

287

У меня есть файл идентификаторов, которые разделены запятыми. Я пытаюсь заменить запятые на новую строку. Я пробовал:

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

Но это не работает. Чего мне не хватает?

WildBill
источник
12
попробуй tr , '\n'. Я полагаю, что sed относится \nк простому тексту.
Принц Джон Уэсли
1
Это сработало! кошачий файл | tr, '\ n'
WildBill
7
tr , '\n' < file- нет трубы.
Принц Джон Уэсли
Для чего нужен gконец сценария? Я получаю такое же поведение без него.
Здравствуйте, до свидания,
Какую оболочку вы используете? Это работает для меня, используя оболочку bash.
Здравствуйте, до свидания,

Ответы:

362

Используйте trвместо этого:

tr , '\n' < file
Принц Джон Уэсли
источник
я искал замену "." период, и это было решением, которое я ищу :)
Иона
1
Это не работает в оболочке bash $ tr, '\ n' использование aitr: tr [-Ccsu] строка1 строка2 tr [-Ccu] -d строка1 tr [-Ccu] -s строка1 tr [-Ccu] -ds строка1 строка2
Учащийся
5
Замена запятой точкой с запятой также работает:tr ',' ';' < input.csv > output.csv
Вим Deblauwe
304

Используйте строку в кавычках ANSI-C $'string'

Вам нужен буквальный перевод строки с обратной косой чертой, чтобы попасть в sed. По крайней мере, в bash $''строки будут заменены \nреальным символом новой строки, но тогда вам придется удвоить обратную косую черту, которую увидит sed, чтобы избежать перехода на новую строку, например

echo "a,b" | sed -e $'s/,/\\\n/g'

Обратите внимание, что это не будет работать на всех оболочках , но будет работать на самых распространенных.

Вальтер Мундт
источник
5
странно, он также работает с один обратный слэш меньше есть echo "a,b" | sed -e $'s/,/\\n/g.
Александр Холден Дейли
2
Upvoted. Для получения дополнительной информации см. Раздел «QUOTING» man bash.
tboyce12
7
Получил работу с OSX 10.11: sed -E $'s/<\\/br>/\\\n/g' fileнет необходимости устанавливать gnu-sed
Brice
2
Проверено работа на OS X 10.7 с приведенным примером. -eЧасть , кажется , не нужно.
Yongwei Wu
1
пример в ответ сразу работает у меня в OSX 10.11.5
Jurriaan Roelofs
122
sed 's/,/\
/g'

работает на Mac OS X.

Макс Нанаси
источник
3
Спасибо за это - Интересно, почему мой старый трюк с Linux не работал в OSX. Но это так!
Wyatt8740
6
Это единственное решение, которое работает в сценарии sed.
Firstrock
6
Обратите внимание, что обратный слеш экранирует буквальный символ новой строки (так что это не терминатор команды): это не символ продолжения строки (как в bash и т. Д.). Чтобы увидеть разницу, попробуйте написать вышеупомянутую команду без кавычек: вместо этого обратная косая черта будет интерпретироваться оболочкой как символ продолжения строки, и она и символ новой строки будут отброшены. И наоборот, включите содержимое выражения в кавычках (без кавычек) в отдельный файл запятой-newline.sed (что исключает синтаксис оболочки), и это работает!
Нильс фон Барт
1
это хорошо, поскольку он может заменить что угодно, а не персонажа. Кажется, tr работает только с персонажами. если вы поместите строку в качестве первого параметра, она заменит все вхождения символов, а не строку.
Шон
1
@Droogans Вы используете bash, sh или другую оболочку? Вы уверены, что используете одинарные кавычки вместо двойных?
Макс Нанаси
22

Если ваше использование sed имеет тенденцию быть полностью выражениями подстановки (как и мое), вы также можете использовать perl -peвместо

$ echo 'foo,bar,baz' | perl -pe 's/,/,\n/g'
foo,
bar,
baz
nar8789
источник
15

Видимо \rэто ключ!

$ sed 's/, /\r/g' file3.txt > file4.txt

Преобразовал это:

ABFS, AIRM, AMED, BOSC, CALI, ECPG, FRGI, GERN, GTIV, HSON, IQNT, JRCC, LTRE,
MACK, MIDD, NKTR, NPSP, PME, PTIX, REFR, RSOL, UBNT, UPI, YONG, ZEUS

К этому:

ABFS
AIRM
AMED
BOSC
CALI
ECPG
FRGI
GERN
GTIV
HSON
IQNT
JRCC
LTRE
MACK
MIDD
NKTR
NPSP
PME
PTIX
REFR
RSOL
UBNT
UPI
YONG
ZEUS
Крис Сеймур
источник
Я знаю, что вопрос говорит об OS X, но это не работает с GNU sed-4.2.2-6.fc20.x86_64.
Кристиан Чиупиту
10
Имейте в виду, что \rэто не то же самое \n, и это может нарушить дальнейшее манипулирование данными и их использование.
Джоэл Пурра,
3
Извините, это не сработало для меня. Я только что получил 'r', где должен быть перевод строки.
Франк де Гроот -
Вы должны сделать это более ясным в ответе, который это дает \r!
пир
Это сработало для меня, но мне интересно, почему! \ n - это стандарт для unix stackoverflow.com/questions/1761051/difference-between-n-and-r
Алекс
15

Это работает на MacOS Mountain Lion (10.8), Solaris 10 (SunOS 5.10) и RHE Linux (Red Hat Enterprise Linux Server версии 5.3, Tikanga) ...

$ sed 's/{pattern}/\^J/g' foo.txt > foo2.txt

... где ^Jэто делается, делая ctrl+ v+ j. Имейте в виду, \прежде чем ^J.

PS Я знаю, что sed в RHEL - это GNU, sed для MacOS - на основе FreeBSD, и хотя я не уверен насчет sed на Solaris, я считаю, что он будет работать практически с любым sed. YMMV tho '...

Рамон Рей
источник
12

MacOS отличается, есть два способа решить эту проблему с помощью Sed в Mac

  • во-первых, используйте \'$'\n''replace \n, он может работать в MacOS:

    sed 's/,/\'$'\n''/g' file
    
  • во-вторых, просто используйте пустую строку:

    sed 's/,/\
    /g' file
    
  • Ps. Обратите внимание на диапазон, разделенный '

  • в-третьих, используйте gnu-sed вместо mac-sed

Cnetwork
источник
7

Чтобы завершить это, это также работает:

echo "a,b" | sed "s/,/\\$(echo -e '\n\r')/"
ryenus
источник
1
Это также подходит для конкурса «Запутанный С», за исключением того, что это Bash;)
Аарон Р.
@AaronR. Я согласен :-). Конечно, я предпочитаю trрешение, которое уже является принятым ответом.
ryenus
1
Это работало на OS X. Почему это \n\rвместо \r\n? Я попытался, \r\nкоторый является необходимым порядком в Windows. Однако после того, как я это сделаю, в нем останется много ^Mсимволов возврата каретки vim, поэтому я думаю, что это должно быть только, \nно \nодиночество не работает.
NobleUplift
4

Хотя я опаздываю на этот пост, просто обновляю свои выводы. Этот ответ только для Mac OS X.

$ sed 's/new/
> /g' m1.json > m2.json
sed: 1: "s/new/
/g": unescaped newline inside substitute pattern

В приведенной выше команде я попытался с помощью Shift + Enter добавить новую строку, которая не работала. Так что на этот раз я попытался "убежать" от "неэкранированного символа новой строки", как было сказано в ошибке.

$ sed 's/new/\
> /g' m1.json > m2.json 

Работал! (в Mac OS X 10.9.3)

user2300875
источник
Это ничем не отличается от ответа Макса Нанаси за два года до твоего.
miken32
2

Просто чтобы прояснить: man-страница sed в OSX (10.8; Darwin Kernel Version 12.4.0) говорит:

[...]

Sed Регулярные выражения

 The regular expressions used in sed, by default, are basic regular expressions (BREs, see re_format(7) for more information), but extended
 (modern) regular expressions can be used instead if the -E flag is given.  In addition, sed has the following two additions to regular
 expressions:

 1.   In a context address, any character other than a backslash (``\'') or newline character may be used to delimit the regular expression.
      Also, putting a backslash character before the delimiting character causes the character to be treated literally.  For example, in the
      context address \xabc\xdefx, the RE delimiter is an ``x'' and the second ``x'' stands for itself, so that the regular expression is
      ``abcxdef''.

 2.   The escape sequence \n matches a newline character embedded in the pattern space.  You cannot, however, use a literal newline charac-
      ter in an address or in the substitute command.

[...]

так что я думаю, что нужно использовать tr - как упомянуто выше - или отличный

sed "s/,/^M
/g"

примечание: вам нужно набрать < ctrl> -v, < return>, чтобы получить '^ M' в редакторе vi

t3az0r
источник
2
$ echo $PATH | sed -e $'s/:/\\\n/g' 
/usr/local/sbin
/Library/Oracle/instantclient_11_2/sdk
/usr/local/bin

...

У меня работает на Мохаве

Пауло Энрике Леллис Гоналвес
источник
1

sedна MacOS Mojave был выпущен в 2005 году, поэтому одним из решений является установка gnu-sed,

brew install gnu-sed

тогда использование gsedбудет делать, как вы хотите,

gsed 's/,/\n/g' file

Если вы предпочитаете sed , просто sudo sh -c 'echo /usr/local/opt/gnu-sed/libexec/gnubin > /etc/paths.d/brew', что предлагается brew info gnu-sed. Перезапустите ваш термин, затем ваш sedв командной строке gsed.

DawnSong
источник
0

FWIW, следующая строка работает в окнах и заменяет точки с запятой в моих переменных пути новой строкой. Я использую инструменты, установленные в моей директории git bin.

echo %path% | sed -e $'s/;/\\n/g' | less
Джефф ЛаФэй
источник