Search code examples
awkcsvfix

Command-line pivot a long table into a wide table


How can I turn a long table like

Room,"Variable Name",Value
Bedroom,Temperature,23
Bedroom,Humidity,78
Office,Temperature,26
Office,Humidity,82
Bathroom,Temperature,18
Bathroom,Humidity,97

Into a wide table like

Room,Temperature,Humidity
Bedroom,23,78
Office,26,82
Bathroom,18,97

At the command line?

I've tried via csvfix flatten -smq but that produces

Room,"Variable Name",Value
Bedroom,Temperature,23,Humidity,78
Office,Temperature,26,Humidity,82
Bathroom,Temperature,18,Humidity,97

Solution

  • Using any awk:

    $ cat tst.awk
    BEGIN { FS=OFS="," }
    {
        key = $1
        hdr = ( NR == 1 ? $1 : $2 )
    
        rowNr = key2row[key] = ( key in key2row ? key2row[key] : ++numRows )
        colNr = hdr2col[hdr] = ( hdr in hdr2col ? hdr2col[hdr] : ++numCols )
    
        vals[rowNr,1] = key
        vals[1,colNr] = hdr
        vals[rowNr,colNr] = $3
    }
    END {
        for ( rowNr=1; rowNr<=numRows; rowNr++ ) {
            for ( colNr=1; colNr<=numCols; colNr++ ) {
                printf "%s%s", vals[rowNr,colNr], (colNr<numCols ? OFS : ORS)
            }
        }
    }
    

    $ awk -f tst.awk file
    Value,Temperature,Humidity
    Bedroom,23,78
    Office,26,82
    Bathroom,18,97