sed & awksed & awkSearch this book

13.9. transpose--Perform a Matrix Transposition

Contributed by Geoff Clare

transpose performs a matrix transposition on its input. I wrote this when I saw a script to do this job posted to the Net and thought it was horribly inefficient. I posted mine as an alternative with timing comparisons. If I remember rightly, the original one stored all the elements individually and used a nested loop with a printf for each element. It was immediately obvious to me that it would be much faster to construct the rows of the transposed matrix "on the fly."

My script uses ${1+"$@"} to supply file names on the awk command line so that if no files are specified awk will read its standard input. This is much better than plain $* which can't handle filenames containing whitexspace.

#! /bin/sh
# Transpose a matrix: assumes all lines have same number
# of fields

exec awk '
NR == 1 {
	n = NF
	for (i = 1; i <= NF; i++)
		row[i] = $i
	next
}
{
	if (NF > n)
		n = NF
	for (i = 1; i <= NF; i++)
		row[i] = row[i] " " $i
}
END {
	for (i = 1; i <= n; i++)
		print row[i]
}' ${1+"$@"}

Here's a test file:

1 2 3 4
5 6 7 8
9 10 11 12

Now we run transpose on the file.

$ transpose test
1 5 9
2 6 10
3 7 11
4 8 12

13.9.1. Program Notes for transpose

This is a very simple but interesting script. It creates an array named row and appends each field into an element of the array. The END procedure outputs the array.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.