I have a CSV delimited by commas and I want to delimit it by newlines instead.


a, b, c



I've written Java parsers that do this stuff, but couldn't this be done with vim or some other tool?

sed isn't working for me:


# Start
cat > infile.csv << __EOF__
a, b, c
cat infile.csv
sed 's/, /\n/g' infile.csv > outfile.csv

cat outfile.csv
  • 2
    This script works as expected on my Ubuntu system – user591 Mar 19 '11 at 18:49

Similar to Iain's answer, you can also use tr:

$ echo a,b,c | tr ',' '\n'

Both answers assume that the CSV is simple (that is, all commas are field separators). If you have something like a,"b,c",d where b,c is a single field, then things get more difficult

| improve this answer | |
  • @Mrozek: how do I use tr with the input and output file? – simpatico Mar 19 '11 at 17:55
  • @simpatico cat input | tr ',' '\n' > output – Michael Mrozek Mar 19 '11 at 18:40
  • 1
    tr ',' '\n' < input > output avoids the UUOC. – kojiro Mar 19 '11 at 23:33
  • 2
    @kojiro Yes, but I do not and never will care about that :). I even do cat foo | grep bar; I suspect the UUOC fanatics burn me in effigy every night – Michael Mrozek Mar 19 '11 at 23:51
  • # As a relative newcomer to Linux/bash, I've been a bit puzzled by the UUOC issue; So, for general info; To cat or not to cat, that is the question... I just time tested 1000 (random) ASCII text files (total 307666 lines)... cat file* | grep sometext vs <file* grep sometext ... 'cat' is slower for real, user, and sys times: real(0m2.396s/0m2.121s): user(0m6.012s/0m3.172s); sys(0m2.264s/0m1.000s) ... (does time matter?.. sometimes yes, soemtimes no)... but the times are certainly different – Peter.O Mar 20 '11 at 16:32

Seems like the other answers achieve what you want, and a scriptable tool seems the most appropriate choice.

But you asked about vim, so here's how you do it there:

%s/, /\r/g

That is, replace every comma+space with a carriage return. This will then be interpreted as the appropriate line ending character for the file. (You can check this by searching for \r -- it won't be found).

| improve this answer | |

The use of \n in a s replacement text in sed is allowed, but not mandated, by POSIX. GNU sed does it, but there are implementations that output \n literally.

You can use any POSIX-compliant awk. Set the input field separator FS to a regular expression and the output field separator ORS to a string (with the usual backslash escapes). The assignment $1=$ is needed to rebuild the line to use the different field separator.

awk -vFS=', *' -vOFS='\n' '{$1=$1; print}'

(This assumes that your input contains plain comma-and-whitespace-separated values, without any quoting. If there is quoting, you need to move to a real CSV parser in a language such as Perl or Python.)

| improve this answer | |

If your file is delimited by ', ' (commas followed by space) then

sed 's/, /\n/g' filename.csv >newfile

will do the job. If its delimited by ',' (commas without spaces) then

sed 's/,/\n/g' filename.csv >newfile

will work.

or change the \n to \o12 if your flavour of sed doesn't like it.

| improve this answer | |
  • this replaced it with space and not new lines. Output: a b c – simpatico Mar 19 '11 at 14:52
  • @simpatico: Ok - I 'see' the problem now, your example output wasn't formatted correctly. – user591 Mar 19 '11 at 15:01
  • @lain: this doens't work with \n . Did you try it? the \ disappears while the n is appended. a, b --> an b – simpatico Mar 19 '11 at 17:57
  • @simpatico: I did test it and it works ok. – user591 Mar 19 '11 at 18:04
  • @Iain GNU sed and sed (some of which are strictly POSIX-compliant) need not necessarily be the same...And I am pretty sure the functionality you tested is guaranteed on GNU sed only. With the others, it may - or may not - work. Like playing poker. :-) – syntaxerror May 9 '15 at 2:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.