transposing square matrixs or blocks in a big file

Hi

I do have a big file of the following format

  a b c d e f g
  2 3 5 6 6 6 7
  3 4 5 6 7 9 0
  4 5 7 8 9 9 0
  1 2 4 5 6 7 8
  3 5 6 7 2 3 4
  5 6 7 4 3 2 4
  5 4 5 6 3 5 5 
  r h i j k l m 
  2 3 4 5 6 7 8
  4 5 7 8 9 9 0
  3 5 6 7 2 3 4
  2 3 5 6 6 6 7
  5 5 7 8 9 2 3
  1 2 4 5 6 7 8
  3 5 6 7 2 3 4

Basically the data is in a matrix format with many square matrixes put together. The bold fonts represents the beginning of such square matrixes. I have shown only 2 such blocks here but I have 100's of such blocks in that file in tab delimited format.

I want to to a transpose (change the axes) of each of the this square matrixes and get a tab delimted file as shown below.

a 2 3 4 1 3 5 5
b 3 4 5 2 5 6 4
c 5 5 7 4 6 7 5
d 6 6 8 5 7 4 6
e 6 7 9 6 2 3 3
f 6 9 9 7 3 2 5
g 7 0 0 8 4 4 5
r 2 4 3 2 5 1 3
h 3 5 5 3 5 2 5
i 4 7 6 5 7 4 6
j 5 8 7 6 8 5 7
k 6 9 2 6 9 6 2
l 7 9 3 6 2 7 3
m 8 0 4 7 3 8 4

Please let me know the best way to do it eith in sed or awk.

LA

---------- Post updated at 05:03 PM ---------- Previous update was at 03:39 PM ----------

Please let me know if there is a way to do this

Do the headers only contain letters and the fields only numbers?

The letters contains both letters and numbers (like letters_numbers) but the fields are always numbers.

Hope this helps.
LA

---------- Post updated at 05:17 PM ---------- Previous update was at 05:16 PM ----------

Sorry a typo

The heads (not letters) contains both letters and numbers (like letters_numbers) but the fields are always numbers.

You can just transpose the small blocks and print and then get the new block, not very memory intensive. What have you tried so far?

try:

 
 awk '
{if(/[a-z]/){x++}
{for(i=1;i<=NF;i++) a[x,NR,i]=$i;t=NR;s=NF
}}
END {for(l=1;l<=x;l++)
{for(m=1;m<=s;m++)
{for(n=1;n<=t;n++) {printf (length(a[l,n,m])>0?a[l,n,m]" ":"")}
{print ""}}}
}' urfile
1 Like

I can transpose block by block but there is like 800 blocks stagged in the file. I don't know how to loop it through.

---------- Post updated at 05:42 PM ---------- Previous update was at 05:32 PM ----------

Hi yinyuemi,

I tested with ur suggestion but its doing it only for the first 2 columns of each block (square matrix). If we could extend it to the 5 more columns in each block that would solve the problem.

Try this, which works as described earlier:

awk 'function pm(){
       for(j=1;j<=NF;j++)
         for(i=1;i<=m;i++)
           printf "%s"(i<m?OFS:RS),M[j,i]
     }
     /[[:alpha:]]/{
       if(m)pm()
       m=0
     }
     {
       ++m
       for(i=1;i<=NF;i++)
         M[i,m]=$i
     }
     END{
       pm()
     }' infile
1 Like

Thanks. I got it working. There was some issue in my data and after correcting it the first awk command itself worked.