Thursday, May 22, 2008

Transpose using awk - BASH


Suppose I have to transpose(converting rows to columns and rows to columns) the following sample file.


$ cat testfile.txt
nixon:nill:xena:raj
23:24:21:12
sbank:london:japan:india


Now we have to transpose the above file. .i.e.

Required Outout:

nixon:23:sbank
nill:24:london
xena:21:japan
raj:12:india



$ awk -F : '{
for(j=1;j<=NF;j++)
{arr[j]=arr[j]":"$j}
}
END {for(i in arr)
print arr[i]}
' testfile.txt | sed 's/^://'


Output:

raj:12:india
nixon:23:sbank
nill:24:london
xena:21:japan


The above awk code is printing the output in a different order, not in the order as they are in the input file.

Here is a better solution:


$ awk -F ":" '{
for (f = 1; f <= NF; f++)
a[NR, f] = $f
}
NF > nf { nf = NF }
END {
for (f = 1; f <= nf; f++)
for (r = 1; r <= NR; r++)
printf a[r, f] (r==NR ? RS : FS)
}' testfile.txt


Output:

nixon:23:sbank
nill:24:london
xena:21:japan
raj:12:india

1 comment:

Anirudh said...



if='testfile.txt'

< $if sed -e 's/$/:/; s/\([^:]*\):/[\1] /g' |
dc -e "
[:] s/ # separator
[q] sq # quit
[SM z 0 b z lN1- >c] sc
[zsN lax lcx lMpc] sd # join stack elements with separator

[l. lC *] se
[z lC - lex + :x z 0 g] sg # for i ( 1 .. R ) { ... }
[lj1+sj 1si lgx ldxc lC lj <h] sh # for j ( 1 .. C ) { ... }
lhx
"

© Jadu Saikia www.UNIXCL.com