350

I have a file of strings that are comma separated. I'm trying to replace the commas with a new line. I've tried:

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

but it is not working. What am I missing?

8
  • 14
    try tr , '\n'. I guess, sed treats \n as plain text. Commented May 25, 2012 at 4:31
  • 1
    That worked! cat file | tr , '\n' Commented May 25, 2012 at 4:37
  • 8
    tr , '\n' < file - no pipe. Commented May 25, 2012 at 4:40
  • What is the g in the end of the script for? I get the same behavior without it. Commented May 27, 2015 at 11:41
  • What shell are you using? This works for me, using the bash shell. Commented May 27, 2015 at 11:47

14 Answers 14

422

Use tr instead:

tr , '\n' < file 
Sign up to request clarification or add additional context in comments.

2 Comments

It is not wokring in bash shell $ tr , '\n' aitr usage: tr [-Ccsu] string1 string2 tr [-Ccu] -d string1 tr [-Ccu] -s string1 tr [-Ccu] -ds string1 string2
Replacing a comma with a semicolon also works: tr ',' ';' < input.csv > output.csv
349

Use an ANSI-C quoted string $'string'

You need a backslash-escaped literal newline to get to sed. In bash at least, $'' strings will replace \n with a real newline, but then you have to double the backslash that sed will see to escape the newline, e.g.

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

Note this will not work on all shells, but will work on the most common ones.

10 Comments

strange, it also works with one backslash less i.e. echo "a,b" | sed -e $'s/,/\\n/g.
Upvoted. For more info see the "QUOTING" section of man bash.
Got it working with OSX 10.11 : sed -E $'s/<\\/br>/\\\n/g' file, no need to install gnu-sed
Verified working on OS X 10.7 with the given example. The -e part seems not necessary.
This is awesome! Using this with fzf for debugging my $PATH in case something is missing: echo $PATH | sed -e $'s/:/\\\n/g' | fzf ^.^
|
134
sed 's/,/\ /g' 

works on Mac OS X.

8 Comments

Thanks for this - Wondered why my old linux trick didn't work in OSX. But this does!
This is the only solution that works in a sed script.
Note that the backslash escapes the literal newline (so that it's not a command terminator): it is not a line continuation character (as in bash, etc.). To see the difference, try to write the above command without the quotes: the backslash will instead be interpreted by the shell as a line continuation character and it and the newline will be discarded. Conversely, include the contents of the quoted expression (without quotes) in a separate comma-to-newline.sed file (which eliminates shell syntax), and it works!
this is good since it can replace anything, not a character. tr seems work with only characters. if you put a string as first parameter, it will replace all the occurrence of the characters, not the string.
@Droogans Are you using bash, sh, or a different shell? Are you sure you're using single quotes instead of double quotes?
|
27

If your sed usage tends to be entirely substitution expressions (as mine tends to be), you can also use perl -pe instead

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

Comments

18

MacOS is different, there is two way to solve this problem with sed in mac

  • first ,use \'$'\n'' replace \n, it can work in MacOS:

    sed 's/,/\'$'\n''/g' file 
  • the second, just use an empty line:

    sed 's/,/\ /g' file 
  • Ps. Pay attention the range separated by '

  • the third, use gnu-sed replace the mac-sed

Comments

17

Apparently \r is the key!

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

Transformed this:

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 

To this:

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 

6 Comments

I know the question says OS X, but this doesn't work with GNU sed-4.2.2-6.fc20.x86_64.
Keep in mind that \r is not the same as \n, and this might break further data manipulation and usage.
Sorry, this didn't work for me. I just got an 'r' where there should be a newline.
You should make it more clear in the answer that this gives \r!
It worked for me but I wonder why! \n is the standard on unix stackoverflow.com/questions/1761051/difference-between-n-and-r
|
16

This works on MacOS Mountain Lion (10.8), Solaris 10 (SunOS 5.10) and RHE Linux (Red Hat Enterprise Linux Server release 5.3, Tikanga)...

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

... where the ^J is done by doing ctrl+v+j. Do mind the \ before the ^J.

PS, I know the sed in RHEL is GNU, the MacOS sed is FreeBSD based, and although I'm not sure about the Solaris sed, I believe this will work pretty much with any sed. YMMV tho'...

Comments

7

To make it complete, this also works:

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

3 Comments

This would also be fitting for the Obfuscated C contest, except it's Bash ;)
@AaronR. I agree :-). Surely I prefer the tr solution, which is already the accepted answer.
This worked on OS X. Why is it \n\r instead of \r\n? I tried \r\n which is the necessary order on Windows. However, after I do this it's leaving a lot of ^M carriage return characters in vim, so I think it's supposed to be only \n but \n alone doesn't work.
4

Though I am late to this post, just updating my findings. This answer is only for Mac OS X.

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

In the above command I tried with Shift+Enter to add new line which didn't work. So this time I tried with "escaping" the "unescaped newline" as told by the error.

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

Worked! (in Mac OS X 10.9.3)

1 Comment

This is no different than Max Nanasy's answer two years before yours.
3
$ echo $PATH | sed -e $'s/:/\\\n/g' /usr/local/sbin /Library/Oracle/instantclient_11_2/sdk /usr/local/bin 

...

Works for me on Mojave

Comments

2

Just to clearify: man-page of sed on OSX (10.8; Darwin Kernel Version 12.4.0) says:

[...]

Sed Regular Expressions

 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. 

[...]

so I guess one have to use tr - as mentioned above - or the nifty

sed "s/,/^M /g" 

note: you have to type <ctrl>-v,<return> to get '^M' in vi editor

Comments

2

The sed on macOS Mojave was released in 2005, so one solution is to install the gnu-sed,

brew install gnu-sed 

then use gsed will do as you wish,

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

If you prefer sed, just sudo sh -c 'echo /usr/local/opt/gnu-sed/libexec/gnubin > /etc/paths.d/brew', which is suggested by brew info gnu-sed. Restart your term, then your sed in command line is gsed.

Comments

0

FWIW, the following line works in windows and replaces semicolons in my path variables with a newline. I'm using the tools installed under my git bin directory.

echo %path% | sed -e $'s/;/\\n/g' | less 

Comments

-1

I have found another command that is working also.

find your_filename.txt -type f -exec sed -i 's/,/\n/g' {} \; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.