I am using an 'awk' command like below, which prints the 4th columns of all .out files containing 'cake':
awk '/cake/{print $4}' ./*/*.out
My output is a column, say:
1
2
3
4
5
6
How can I reformat this to something that looks like:
1 4
2 5
3 6
or
1 3 5
2 4 6
i.e. have a set number of column elements (3 and 2 in the above cases).
Better yet, can I make it spit out the output as a csv file within the same command?
Thank you.
You can do it with awk
itself, but I prefer pr
for this
$ # -2 is number of columns needed
$ # -s option specifies delimiter, default is tab
$ seq 6 | pr -2ts','
1,4
2,5
3,6
$ seq 6 | pr -3ts','
1,3,5
2,4,6
$ # you can also change horizontal/vertical order
$ seq 6 | pr -3ats','
1,2,3
4,5,6
$ cat tst.awk
{ a[NR] = $0 }
END {
OFS = ","
numCols = (numCols ? numCols : 1)
numRows = ceil(NR / numCols)
for ( rowNr=1; rowNr<=numRows; rowNr++ ) {
for ( colNr=1; colNr<=numCols; colNr++ ) {
idx = rowNr + ( (colNr - 1) * numRows )
printf "%s%s", a[idx], (colNr<numCols ? OFS : ORS)
}
}
}
function ceil(x, y){y=int(x); return(x>y?y+1:y)}
$ awk -v numCols=2 -f tst.awk file
1,4
2,5
3,6
$ awk -v numCols=3 -f tst.awk file
1,3,5
2,4,6
Note that the above will work even if your number of input rows isn't an exact multiple of the number of columns you want (note that there's 3 comma-separated fields even in the lines with empty fields):
$ seq 10 | awk -v numCols=3 -f tst.awk
1,5,9
2,6,10
3,7,
4,8,
See https://stackoverflow.com/a/56725768/1745001 for how to do the opposite, i.e. generate a number of columns given a specified number of rows.