是否可以将以下数据矩阵输入转置到所需的输出?
f1 x1 1.2
f1 x2 2.2
f1 x3 0
f2 x1 1.1
f2 x2 1.2
f2 x3 3.3
f3 x1 2.3
f3 x2 4.4
f3 x3 0.1
输出
f1 f2 f3
x1 1.2 1.1 2.3
x2 2.2 1.2 4.4
x3 0 3.3 0.1
答案 0 :(得分:1)
这可以是一种方式:
awk '{a[$1,$2]=$3; col[$1]; row[$2]}
END {printf "%s", FS
for (c in col) printf "%s%s", c, FS; print "";
for (r in row) {
printf "%s%s", r, FS
for (c in col) printf "%s%s", a[c,r], FS
print ""
}
}' file
这是非常具有描述性的,但仍然是:
a[col, row]
。读取文件后,循环显示结果并打印。
对于给定的输入,它返回:
$ awk '{a[$1,$2]=$3; col[$1]; row[$2]} END {printf "%s", FS; for (c in col) printf "%s%s", c, FS; print ""; for (r in row) { printf "%s%s", r, FS; for (c in col) printf "%s%s", a[c,r], FS; print ""}}' a
f1 f2 f3
x1 1.2 1.1 2.3
x2 2.2 1.2 4.4
x3 0 3.3 0.1
答案 1 :(得分:0)
% cat mat.rix
f1 x1 1.2
f1 x2 2.2
f1 x3 0
f2 x1 1.1
f2 x2 1.2
f2 x3 3.3
f3 x1 2.3
f3 x2 4.4
f3 x3 0.1
% cat a.wk
{
if(! row[$1]) { i=i+1; rowname[i]=$1; row[$1]=1 }
if(! col[$2]) { j=j+1; colname[j]=$2; col[$2]=1 }
if(c[$2])
c[$2] = sprintf("%s%s%10.4f", c[$2], OFS, $3)
else
c[$2] = sprintf("%10.4f", $3)
}
END {
printf " "
for(n=1;n<i+1;n++){ printf "%10s%s", rowname[n], OFS } ; print ""
for(n=1;n<j+1;n++){ print colname[n], c[colname[n]] }}
% awk -f a.wk mat.rix
f1 f2 f3
x1 1.2000 1.1000 2.3000
x2 2.2000 1.2000 4.4000
x3 0.0000 3.3000 0.1000
%
如果列名称的长度不同,该怎么办?
% cat aw.k
{
if(! row[$1]) { i=i+1; rowname[i]=$1; row[$1]=1 }
if(! col[$2]) { j=j+1; colname[j]=$2; col[$2]=1 }
if(c[$2])
c[$2] = sprintf("%s%s%10.4f", c[$2], OFS, $3)
else
c[$2] = sprintf("%10.4f", $3)
}
END {
for(n=1;n<j+1;n++){l = length(colname[n]) ; if(l>lmax) lmax=l}
format = sprintf("%%-%ds%%s%%s\n", lmax)
for(n=1;n<lmax+1;n++) printf "."; printf OFS
for(n=1;n<i+1;n++){ printf "%10s%s", rowname[n], OFS } ; print ""
for(n=1;n<j+1;n++){ printf(format, colname[n], OFS, c[colname[n]])}
}
% awk -f aw.k mat.rix
.. f1 f2 f3
x1 1.2000 1.1000 2.3000
x2 2.2000 1.2000 4.4000
x3 0.0000 3.3000 0.1000
%
使用%%
format
时,请考虑使用sprintf