------------------------------------------------------------------------
Convert a column to a matrix
------------------------------------------------------------------------

Say you have a column of data, length n, and you wish to write it
as a matrix with dimensions (nr,nc) where nr is the number of rows
and nc is the number of columns.

For the purpose of this exercise we will generate the requisite
column in one of several ways:

$ echo {01..12} | xargs -n 1 | tee infile
01
02
03
04
05
06
07
08
09
10
11
12

$ paste -d "\n" <(seq 12) | tee infile     #generates a similar file
$ seq 12 | paste -d "\n" -  | tee infile   #ditto
$ seq 12 | xargs -n 1  | tee infile        #ditto
 

Say you want to convert "infile" to (3,4) matrix. This is easily done:

$ cat infile | xargs -n 3
01 02 03
04 05 06
07 08 09
10 11 12

But say, you wanted the transpose. I thought it was not possible to
do with standard Unix tools. So I wrote a program which can do this.
However, recently, I discovered a pure Unix tool approach and this
is described in "pr" (see Tools webpage).

In any case, here is the program.

$ col2mat -n 3 infile
01 04 07 10
02 05 08 11
03 06 09 12


The program can also use other delimiters:
$ col2mat -n 3 -d "," infile
01,04,07,10
02,05,08,11
03,06,09,12


------------------------------------------------------------------------
$ cat col2mat
------------------------------------------------------------------------

#!/bin/bash
#
#	 col2mat -n nrow [-d delim] infile
#
# print matrix (nrow, ncol) of infile which has N rows (N=nrow*ncol)
# delim is single-char delimator such as , : ";" "\t"
#
# example 
# $ seq 9 
#
# $ col2mat -n 3 <(seq 9)
# 1 4 7
# 2 5 8
# 3 6 9
# $ col2mat -n 3 -d : <(seq 9)

# limitations: number of rows < 100

if [ $# -lt 3 ] || [ $# -eq 4 ]; then
        printf "incorrect number of arguments %d\n" $#; exit -1
fi

if [ $# -eq 3 ]; then
   	if [ $1 != "-n" ]; then
		printf "%s: incorrect option\n" $1; exit -1
   	fi
        nrow=$2; fs=" "; shift 2
else
	if [ $1 != "-n" ] || [ $3 != "-d" ]; then
	  printf "%s %s: incorrection option(s)\n" $1, $3; exit -1
        fi
   	nrow=$2; fs=$4; shift 4
fi

if [ $nrow -ge 100 ]; then
	printf "requesting %d rows which exceed limit\n" $nrow
	exit -1
fi

awk -v nr=$nrow '{
    	i=int((NR-1)/nr+1)
	ind=sprintf("%02d",i) 
    	print $0  > "T_" ind ".tmp"}' $1

paste -d "$fs" T_[0-9][1-9].tmp 
rm T_[0-9][1-9].tmp               #clean up