Zastąp przecinek nową linią w sed na MacOS?

287

Mam plik identyfikatorów oddzielonych przecinkami. Próbuję zastąpić przecinki nową linią. Próbowałem:

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

ale to nie działa. czego mi brakuje?

WildBill
źródło
12
spróbuj tr , '\n'. Myślę, że sed traktuje \njak zwykły tekst.
Prince John Wesley,
1
To się udało! plik kota | tr, '\ n'
WildBill
7
tr , '\n' < file- bez rury.
Książę John Wesley,
Do czego służy gkoniec skryptu? Bez tego mam takie samo zachowanie.
HelloGoodbye
Jakiej powłoki używasz? Działa to dla mnie przy użyciu powłoki bash.
HelloGoodbye

Odpowiedzi:

362

trZamiast tego użyj :

tr , '\n' < file
Książę John Wesley
źródło
szukałem zamiany „”. kropka i to było rozwiązanie, którego szukam :)
Jonah
1
Nie działa w powłoce bash $ tr, '\ n' aitr użycie: tr [-Ccsu] string1 string2 tr [-Ccu] -d string1 tr [-Ccu] -s string1 tr [-Ccu] -ds string1 string2
Uczeń
5
Zastępowanie przecinka średnikiem również działa:tr ',' ';' < input.csv > output.csv
Wim Deblauwe
304

Użyj ciągu cytowanego ANSI-C $'string'

Potrzebujesz dosłownego znaku nowej linii, aby uciec. Przynajmniej w bash $''ciągi zostaną zastąpione \nprawdziwą nową linią, ale wtedy musisz podwoić odwrotny ukośnik, aby sed zobaczył, by uciec przed nową linią, np.

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

Zauważ, że to nie zadziała na wszystkich powłokach , ale zadziała na najpopularniejszych.

Walter Mundt
źródło
5
dziwne, działa również z jednym ukośnikiem mniejszym, tj echo "a,b" | sed -e $'s/,/\\n/g.
Alexandre Holden Daly,
2
Pozytywne. Aby uzyskać więcej informacji, zobacz sekcję „CYTOWANIE” w man bash.
tboyce12
7
Działa z OSX 10.11: sed -E $'s/<\\/br>/\\\n/g' filenie trzeba instalować gnu-sed
Brice
2
Zweryfikowano działanie na OS X 10.7 z podanym przykładem. Ta -eczęść wydaje się niepotrzebna.
Yongwei Wu
1
przykład w odpowiedzi od razu działa dla mnie w OSX 10.11.5
Jurriaan Roelofs
122
sed 's/,/\
/g'

działa na Mac OS X.

Max Nanasy
źródło
3
Dzięki za to - zastanawiałem się, dlaczego moja stara sztuczka z Linuksem nie działała w OSX. Ale to robi!
Wyatt8740
6
To jedyne rozwiązanie, które działa w skrypcie sed.
Firstrock
6
Zauważ, że backslash wymyka dosłowne przełamane (tak, to nie jest terminator poleceń): to nie postać linia kontynuacji (jak w bash, itd.). Aby zobaczyć różnicę, spróbuj napisać powyższe polecenie bez cudzysłowów: odwrotny ukośnik zostanie zinterpretowany przez powłokę jako znak kontynuacji linii, a on i nowa linia zostaną odrzucone. I odwrotnie, uwzględnij treść cytowanego wyrażenia (bez cudzysłowów) w osobnym pliku przecinka-newline.sed (co eliminuje składnię powłoki) i działa!
Nils von Barth,
1
jest to dobre, ponieważ może zastąpić wszystko, a nie postać. tr wydaje się działać tylko z postaciami. jeśli jako pierwszy parametr podasz ciąg znaków, zastąpi on wszystkie występujące znaki, a nie ciąg.
Shawn
1
@Droogans Czy używasz bash, sh lub innej powłoki? Czy na pewno używasz pojedynczych cudzysłowów zamiast podwójnych?
Max Nanasy,
22

Jeśli twoje użycie sed jest zazwyczaj wyrażeniem podstawienia (tak jak moje), możesz również użyć perl -petego

$ echo 'foo,bar,baz' | perl -pe 's/,/,\n/g'
foo,
bar,
baz
nar8789
źródło
15

Najwyraźniej \rjest kluczem!

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

Przekształciłem to:

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

Do tego:

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
Chris Seymour
źródło
Wiem, że pytanie mówi OS X, ale to nie działa z GNU sed-4.2.2-6.fc20.x86_64.
Cristian Ciupitu
10
Pamiętaj, że \rto nie to samo \n, co może zakłócić dalszą manipulację danymi i ich wykorzystanie.
Joel Purra
3
Przepraszam, to nie działało dla mnie. Właśnie dostałem „r”, gdzie powinna być nowa linia.
Frank de Groot - Schouten
Powinieneś wyjaśnić to w odpowiedzi, którą to daje \r!
pir
To działało dla mnie, ale zastanawiam się, dlaczego! \ n jest standardem w unix stackoverflow.com/questions/1761051/difference-between-n-and-r
Alex
15

Działa na MacOS Mountain Lion (10.8), Solaris 10 (SunOS 5.10) i RHE Linux (Red Hat Enterprise Linux Server wersja 5.3, Tikanga) ...

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

... gdzie ^Jto się robi, wykonując ctrl+v + j. Nie przeszkadza to \przed ^J.

PS, wiem, że sed w RHEL jest GNU, sed MacOS jest oparty na FreeBSD i chociaż nie jestem pewien co do sed Solaris, wierzę, że będzie działać prawie z każdym sedem. YMMV tho ...

Ramon Rey
źródło
12

MacOS jest inny, istnieją dwa sposoby rozwiązania tego problemu z sed w mac

  • najpierw użyj \'$'\n''replace \n, może działać w systemie MacOS:

    sed 's/,/\'$'\n''/g' file
    
  • po drugie, użyj pustej linii:

    sed 's/,/\
    /g' file
    
  • Ps. Zwróć uwagę na przedział oddzielony '

  • po trzecie, użyj gnu-sed zamień mac-sed

Cnetwork
źródło
7

Aby to zakończyć, działa to również:

echo "a,b" | sed "s/,/\\$(echo -e '\n\r')/"
ryenus
źródło
1
Byłoby to również odpowiednie dla konkursu Obfuscated C, z wyjątkiem Bash;)
Aaron R.
@AaronR. Zgadzam się :-). Z pewnością wolę trrozwiązanie, które jest już przyjętą odpowiedzią.
ryenus
1
To działało na OS X. Dlaczego jest to \n\rzamiast \r\n? Próbowałem, \r\nktóra jest niezbędna kolejność w systemie Windows. Jednak po zrobieniu tego pozostawia wiele ^Mznaków powrotu karetki vim, więc myślę, że to powinno być tylko, \nale \nsam nie działa.
NobleUplift
4

Chociaż spóźniłem się na ten post, po prostu aktualizuję swoje ustalenia. Ta odpowiedź dotyczy tylko systemu Mac OS X.

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

W powyższym poleceniu próbowałem z Shift + Enter, aby dodać nową linię, która nie działała. Więc tym razem próbowałem z „ucieczką” do „nowej linii bez zmian”, jak powiedział błąd.

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

Pracował! (w Mac OS X 10.9.3)

użytkownik2300875
źródło
Nie różni się to od odpowiedzi Maxa Nanasy'ego sprzed dwóch lat.
miken32
2

Dla wyjaśnienia: strona podręcznika użytkownika sed w OSX (10.8; Darwin Kernel wersja 12.4.0) mówi:

[...]

Sed Wyrażenia regularne

 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.

[...]

więc myślę, że trzeba użyć tr - jak wspomniano powyżej - lub sprytnego

sed "s/,/^M
/g"

Uwaga: musisz wpisać < ctrl> -v, < return>, aby uzyskać '^ M' w edytorze vi

t3az0r
źródło
2
$ echo $PATH | sed -e $'s/:/\\\n/g' 
/usr/local/sbin
/Library/Oracle/instantclient_11_2/sdk
/usr/local/bin

...

Działa dla mnie na Mojave

Paulo Henrique Lellis Gonalves
źródło
1

sedna macOS Mojave została wydana w 2005 roku, więc jednym z rozwiązań jest instalacja gnu-sed,

brew install gnu-sed

wtedy użycie gsedzrobi to, co chcesz,

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

Jeśli wolisz sed, po prostu sudo sh -c 'echo /usr/local/opt/gnu-sed/libexec/gnubin > /etc/paths.d/brew', co sugeruje brew info gnu-sed. Uruchom ponownie termin, a następnie sedw wierszu polecenia jest gsed.

DawnSong
źródło
0

FWIW, następujący wiersz działa w systemie Windows i zastępuje średniki w moich zmiennych ścieżki nową linią. Korzystam z narzędzi zainstalowanych w moim katalogu git bin.

echo %path% | sed -e $'s/;/\\n/g' | less
Jeff LaFay
źródło