Using awk
$ awk -v RS='[,\n]' '{a=$0;getline b; getline c; print a,b,c}' OFS=, filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
How it works
-v RS='[,\n]'
This tells awk to use any occurrence of either a comma or a newline as a record separator.
a=$0; getline b; getline c
This tells awk to save the current line in variable a
, the next line in varaible b
, and the next line after that in variable c
.
print a,b,c
This tells awk to print a
, b
, and c
OFS=,
This tells awk to use a comma as the field separator on output.
Using tr
and paste
$ tr , '\n' <filename | paste -d, - - -
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
How it works
tr , '\n' <filename
This reads from filename while converting all commas to newlines.
paste -d, - - -
This paste
to read three lines from stdin (one for each -
) and paste them together, each separated by a comma (-d,
).
Alternate awk
$ awk -v RS='[,\n]' '{printf "%s%s",$0,(NR%3?",":"\n")}' filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
How it works
-v RS='[,\n]'
This tells awk to use any occurrence of either a comma or a newline as a record separator.
printf "%s%s",$0,(NR%3?",":"\n")
This tells awk to print the current line followed by either a comma or a newline depending the value of the current line number, NR
, modulo 3.
rs
(the "reshape" command).rs -c, -C, 0 3 <<<'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O'
has you most of the way there. – Toby Speight Mar 16 '18 at 13:31