用awk和sed实现矩阵转置
2024-04-10 01:20:07  阅读数 767

输入矩阵:input.txt

cat input.txt 
ID  par1  par2  par3
a  7  67  90
b  8  89  56
c  6  87  66
d  5  89  3
e  9  78  67

利用awk和sed将矩阵转置

awk '{i=1;while(i <= NF){new[i]=new[i] $i "\t";i=i+1}} END {i=1;while(i<=NF){print new[i];i=i+1}}' input.txt | sed 's/[\t]$//g' > transposition.txt

代码详解:

NF代表每一行的字段总数,即列数,在这里为4

1代表第一列,2代表第二列

awk是按行读取

读取第一行,

i=1,i<=4,因此new[1]=new[1] $1 "\t",因为最初并未给new赋值,所以此时new[1]=ID"\t"

i=i+1=2,i<=4,因此new[2]=new[2] $2 "\t" ,此时new[2]=par1"\t"

i=i+1=3,i<=4,因此new[3]=new[3] $3 "\t",此时new[3]=par2"\t"

i=i+1=4,i<=4,因此new[4]=new[4] $4 "\t",此时new[4]=par3"\t"

i=i+1=4,i>4,跳出循环

读取第二行

i=1,i<=4,因此new[1]=new[1] $1 "\t",读取第一行时给new赋值,所以此时new[1]=ID"\t"a"\t"

i=i+1=2,i<=4,因此new[2]=new[2] $2 "\t" ,此时new[2]=par1"\t"7"\t"

i=i+1=3,i<=4,因此new[3]=new[3] $3 "\t",此时new[3]=par2"\t"67"\t"

i=i+1=4,i<=4,因此new[4]=new[4] $4 "\t",此时new[4]=par3"\t"90"\t"

i=i+1=4,i>4,跳出循环

依次读取第三行到最后一行,得到:

new[1]=ID"\t"a"\t"b"\t"c"\t"d"\t"e"\t"

new[2]=par1"\t"7"\t"8"\t"6"\t"5"\t"9"\t"

new[3]=par2"\t"67"\t"89"\t"87"\t"89"\t"78"\t"

new[4]=par3"\t"90"\t"56"\t"66"\t"3"\t"67"\t"

然后将new打印出即可

使用awk转置后每行末尾会产生一个多余的tab键,需用sed删除,其中[]代表匹配一个指定范围内的字符,$代表行结束符

转置后的矩阵:

cat transposition.txt 
ID  a  b  c  d  e
par1  7  8  6  5  9
par2  67  89  87  89  78
par3  90  56  66  3  67