Jan Rostenkowski
Jan Rostenkowski

Reputation: 325

How can I make a multiple-column output with 'awk' command?

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.

Upvotes: 1

Views: 201

Answers (2)

Ed Morton
Ed Morton

Reputation: 203209

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

Upvotes: 2

Sundeep
Sundeep

Reputation: 23667

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

Upvotes: 5

Related Questions