ChatGPT解决这个技术问题 Extra ChatGPT

Replace comma with newline in sed on MacOS?

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?

try tr , '\n'. I guess, sed treats \n as plain text.
That worked! cat file | tr , '\n'
tr , '\n' < file - no pipe.
What is the g in the end of the script for? I get the same behavior without it.
What shell are you using? This works for me, using the bash shell.

P
Prince John Wesley

Use tr instead:

tr , '\n' < file

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
m
miken32

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.


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 ^.^
M
Max Nanasy
sed 's/,/\
/g'

works on Mac OS X.


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?
n
nar8789

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

F
Felix

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


C
Chris Seymour

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

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
J
Joel Purra

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'...


r
ryenus

To make it complete, this also works:

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

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.
N
Nils von Barth

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)


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

...

Works for me on Mojave


t
t3az0r

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 -v, to get '^M' in vi editor


D
DawnSong

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.


J
Jeff LaFay

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

s
shawon

I have found another command that is working also.

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