Замінити кому новою лінією на sed на MacOS?


287

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

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

але це не працює. Що я пропускаю?


12
спробуйте tr , '\n'. Я думаю, sed трактує \nяк звичайний текст.
Принц Джон Веслі

1
Це спрацювало! файл котів | tr, '\ n'
WildBill

7
tr , '\n' < file- жодної труби.
Принц Джон Веслі

Для чого gв кінці сценарій? Я отримую таку ж поведінку і без цього.
HelloGoodbye

Яку оболонку ви використовуєте? Це працює для мене, використовуючи bash shell.
HelloGoodbye

Відповіді:


362

Використовуйте trзамість цього:

tr , '\n' < file

я шукав заміни "." періоду, і це було рішення, яке я шукаю :)
Jonah

1
Це не вокрінг в оболонці bash $ tr, '\ n' aitr використання: tr [-Ccsu] string1 string2 tr [-Ccu] -d string1 tr [-Ccu] -s string1 tr [-Ccu] -ds string1 string2
Учень

5
Заміна коми крапкою з комою також працює:tr ',' ';' < input.csv > output.csv
Вім Деблауве

304

Використовуйте рядок, цитований ANSI-C $'string'

Щоб дістатися до sed, вам потрібен буквальний новий рядок, що вийшов з косою рискою. Принаймні в баші, $''рядки замінять \nсправжній новий рядок, але тоді вам доведеться подвоїти зворотну косу рису, яку Sed побачить, щоб вийти з нового рядка, наприклад

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

Зауважте, це працюватиме не на всіх оболонках , але буде працювати на найбільш поширених.


5
дивно, він також працює з одним зворотним нахилом менше, тобто echo "a,b" | sed -e $'s/,/\\n/g.
Олександр Холден Далі

2
Оголошено. Для отримання додаткової інформації дивіться розділ "ЦИТУРА" 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 тощо). Щоб побачити різницю, спробуйте написати вищевказану команду без лапок: зворотний косий рисок натомість буде інтерпретований оболонкою як символ продовження рядка, і він, і новий рядок будуть відкинуті. І навпаки, включіть вміст цитованого виразу (без лапок) в окремий файл з комою до нового рядка.sed (який виключає синтаксис оболонки), і він працює!
Нілс фон Барт

1
це добре, оскільки може замінити що завгодно, а не персонажа. tr здається, робота лише з персонажами. якщо ви введете рядок як перший параметр, він замінить все виникнення символів, а не рядок.
Шон

1
@Droogans Ви використовуєте bash, sh чи іншу оболонку? Ви впевнені, що замість подвійних лапок використовуєте одинарні лапки?
Макс Нанасі

22

Якщо використання седу має вираз заміни (як у мене зазвичай), ви також можете використовувати його perl -peзамість цього

$ echo 'foo,bar,baz' | perl -pe 's/,/,\n/g'
foo,
bar,
baz

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, MacOS sed - це FreeBSD, і, хоча я не впевнений у відношенні Solaris sed, я вважаю, що це спрацює дуже багато з будь-яким седом. YMMV Тхо ...


12

MacOS відрізняється, існує два способи вирішити цю проблему з sed in mac

  • по-перше, використовувати \'$'\n'' заміну \n, вона може працювати в MacOS:

    sed 's/,/\'$'\n''/g' file
    
  • друге, просто використовуйте порожній рядок:

    sed 's/,/\
    /g' file
    
  • Пс. Зверніть увагу на діапазон, розділений на '

  • по-третє, використовувати gnu-sed замінити mac-sed


7

Для завершення роботи це також працює:

echo "a,b" | sed "s/,/\\$(echo -e '\n\r')/"

1
Це також підходило б до змагань «Замкнутий С», за винятком Баша;)
Аарон Р.

@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)


Це нічим не відрізняється від відповіді Макса Нанасі за два роки до вашого.
miken32

2

Просто для очищення: man-page 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



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.


0

FWIW, наступний рядок працює у Windows і замінює крапки з комою в змінних мого шляху новим рядком. Я використовую інструменти, встановлені в моєму каталозі git bin.

echo %path% | sed -e $'s/;/\\n/g' | less
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.