Convert one column to three comma delimited columns using awk
$ awk '{printf "%s%s",$0,NR%3?",":"\n";}' file
Xaa,Ybb,Mdd
Tmmn,UUnx,THM
THSS,THEY,DDe
How it works
For each line of input, this prints a line followed, depending on the line number, by a comma or a new line.
The key part is this ternary statement:
NR%3?",":"\n"
This takes a line number modulo 3. If it is nonzero, then it returns a comma. If it is zero, it returns a newline character.
Processing files that end before the end of the last line
It is assumed that the number of lines in the file is an integer multiple of three. If it doesn't, we probably want to make sure the last line has a newline. This can be done, as Jonathan Leffler suggests, using:
awk '{printf "%s%s",$0,NR%3?",":"\n";} END { if (NR%3 != 0) print ""}' file
If the final row does not contain three columns, the above code will leave a trailing comma in the row. This may or may not be a problem. If we don't want the last comma, use:
awk 'NR==1{printf "%s",$0; next} {printf "%s%s",(NR-1)%3?",":"\n",$0;} END {print ""}' file
Jonathan Leffler suggests this slightly simpler alternative to achieve the same goal:
awk '{ printf("%s%s", pad, $1); pad = (NR%3 == 0) ? "\n" : "," } END { print "" }'
Improved portability
To support platforms that do not use \n
a string terminator, Ed Morton suggests:
awk -v OFS=, '{ printf("%s%s", pad, $1); pad = (NR%3?OFS:ORS)} END { print "" }' file
source to share
xargs -n3 < file | awk -v OFS="," '{$1=$1} 1'
xargs
uses echo
as default action, $1=$1
forcibly restores $0
.
Using awk only, I would go with this (which is similar to what @ jonathan-leffler and @ John1024 suggested)
{
sep = NR == 1 ? "" : \
(NR-1)%3 ? "," : \
"\n"
printf sep $0
}
END {
printf "\n"
}
source to share