Rotating a file: converting row data to column data

This entry was posted by on Tuesday, 13 September, 2011 at

Say you have a file with data line-by-line, but you want it to be column-by-column, like this:

                1 a
1 2 3 4         2 b        
a b c d   -->   3 c
                4 d

So behaviour becomes similar to Matlab’s rot90 or transpose function, rotating the file 90 degrees counterclockwise*. This stuff may be of interest if we want to plot columns (like, for every digit plot its corresponding letter). Here’s how it’s done:

I wrote a little script that does exactly this:

$ cat myData.dat
1 2 3 4 
a b c d
$ ./transpose.sh myData.dat 
1       a 
2       b 
3       c 
4       d 

Here are the contents of transpose.sh:

#!/bin/bash

# a script to convert space-separated row data into tab-separated column data 
# behaviour similar to Matlab's rot90 function
# @assume: the file is complete, i.e. NF is the same for each line
 
cat $1 | awk 'BEGIN{}
{ 
    if (max_nf < NF){
        max_nf = NF
    }
    max_nr = NR
    for (x = 1; x <= NF; x++){
        a[x, NR] = $x
    } 
}
END{
    for(i=1;i<=max_nf;i++){
        for(j=1;j<=max_nr;j++){
            printf("%s \t",a[i,j]);
        }
        printf("\n");
    }
}'

There you have it, we converted a file with data arranged per line into a file with a tab-separated column-based format. If you put the file in your path (for instance, in a ~/bin directory) and call it 'transpose', then you can use it systemwide like this:

$ transpose myData.dat 

* the careful reader may notice it is not exactly rot90 behaviour, but rather rot90 followed by flipui, or rot90(data,3) or a simple transpose 😉


Leave a Reply