我有一个纬度经度和温度的数据矩阵,格式如下:
15W 14.5W 14W 13.5W 13W
30N 19.3 19.3 19.2 18.9 18.6
30.5N 19.1 19 19 18.9 18.4
31N 18.9 18.8 18.7 18.6 18.3
31.5N 18.9 18.7 18.7 18.6 18.1
32N 18.6 18.5 18.6 18.5 17.5
我想使用awk将其转换为纬度经度和温度的行。 输出应如下所示:
15W 30N 19.3
15W 30.5N 19.1
15W 31N 18.9
15W 31.5N 18.9
15W 32N 18.6
14.5W 30N 19.3
14.5W 30.5N 19
14.5W 31N 18.8
我想你明白了。我想到了awk,因为我已经用它做了一些其他事情并且它非常强大。但也许在这里可以使用其他一些工具。
行数和列数并不总是相同。
我还需要将纬度和经度转换为十进制分钟,但我一步一步。
答案 0 :(得分:3)
awk 'NR==1{for(i=1;i<=NF;i++)t[i]=$i}{ r[NR]=$1; for(i=2;i<=NF;i++) v[t[i-1],$1]=$i}END{for(i=1;i<=length(t);i++) for(j=2;j<=NR;j++) print t[i], r[j], v[t[i],r[j]]
} ' file
我想将上面的单行格式化为“三行”:):
awk 'NR==1{for(i=1;i<=NF;i++)t[i]=$i}
{ r[NR]=$1; for(i=2;i<=NF;i++) v[t[i-1],$1]=$i}
END{for(i=1;i<=length(t);i++)for(j=2;j<=NR;j++)print t[i], r[j], v[t[i],r[j]]} ' file
试验:
kent$ cat t
15W 14.5W 14W 13.5W 13W
30N 19.3 19.3 19.2 18.9 18.6
30.5N 19.1 19 19 18.9 18.4
31N 18.9 18.8 18.7 18.6 18.3
31.5N 18.9 18.7 18.7 18.6 18.1
32N 18.6 18.5 18.6 18.5 17.5
kent$ awk 'NR==1{for(i=1;i<=NF;i++)t[i]=$i}
{ r[NR]=$1; for(i=2;i<=NF;i++) v[t[i-1],$1]=$i}
END{for(i=1;i<=length(t);i++)for(j=2;j<=NR;j++)print t[i], r[j], v[t[i],r[j]]} ' t
15W 30N 19.3
15W 30.5N 19.1
15W 31N 18.9
15W 31.5N 18.9
15W 32N 18.6
14.5W 30N 19.3
14.5W 30.5N 19
14.5W 31N 18.8
14.5W 31.5N 18.7
14.5W 32N 18.5
14W 30N 19.2
14W 30.5N 19
14W 31N 18.7
14W 31.5N 18.7
14W 32N 18.6
13.5W 30N 18.9
13.5W 30.5N 18.9
13.5W 31N 18.6
13.5W 31.5N 18.6
13.5W 32N 18.5
13W 30N 18.6
13W 30.5N 18.4
13W 31N 18.3
13W 31.5N 18.1
13W 32N 17.5
答案 1 :(得分:1)
解决方案不需要复杂。一旦选择了正确的数据结构,它实际上相当简单。只需使用GNU awk
即可使用真正的多维数组。像:
awk -f script.awk file
script.awk
的内容:
NR==1 {
for (i=1;i<=NF;i++) {
a[i]=$i
}
next
}
{
for (j=2;j<=NF;j++) {
b[j-1][NR]["rec"] = a[j-1] FS $1 FS $j
b[j-1][NR]["val"] = $j
}
}
END {
for (x=1;x<=length(b);x++) {
for (y=2;y<=NR;y++) {
if (b[x][y]["val"] != "999.9") {
print b[x][y]["rec"] | "column -t"
}
}
}
}
结果:
15W 30N 19.3
15W 30.5N 19.1
15W 31N 18.9
15W 31.5N 18.9
15W 32N 18.6
14.5W 30N 19.3
14.5W 30.5N 19
14.5W 31N 18.8
14.5W 31.5N 18.7
14.5W 32N 18.5
14W 30N 19.2
14W 30.5N 19
14W 31N 18.7
14W 31.5N 18.7
14W 32N 18.6
13.5W 30N 18.9
13.5W 30.5N 18.9
13.5W 31N 18.6
13.5W 31.5N 18.6
13.5W 32N 18.5
13W 30N 18.6
13W 30.5N 18.4
13W 31N 18.3
13W 31.5N 18.1
13W 32N 17.5
或者,这是单行:
awk 'NR==1 { for (i=1;i<=NF;i++) a[i]=$i; next } { for (j=2;j<=NF;j++) { b[j-1][NR]["rec"] = a[j-1] FS $1 FS $j; b[j-1][NR]["val"] = $j } } END { for (x=1;x<=length(b);x++) for (y=2;y<=NR;y++) if (b[x][y]["val"] != "999.9") print b[x][y]["rec"] | "column -t" }' file
答案 2 :(得分:1)
awk 'NR==1{n=split($0,a," ")}NR!=1{for(i=1;i<=n;i++)x[a[i]" "$1]=$(i+1);}END{for(i in x){print i,x[i]}}' temp | sort
测试如下:
> cat temp
15W 14.5W 14W 13.5W 13W
30N 19.3 19.3 19.2 18.9 18.6
30.5N 19.1 19 19 18.9 18.4
31N 18.9 18.8 18.7 18.6 18.3
31.5N 18.9 18.7 18.7 18.6 18.1
32N 18.6 18.5 18.6 18.5 17.5
phoenix.250> nawk 'NR==1{n=split($0,a," ")}NR!=1{for(i=1;i<=n;i++)x[a[i]" "$1]=$(i+1);}END{for(i in x){print i,x[i]}}' temp | sort
13.5W 30.5N 18.9
13.5W 30N 18.9
13.5W 31.5N 18.6
13.5W 31N 18.6
13.5W 32N 18.5
13W 30.5N 18.4
13W 30N 18.6
13W 31.5N 18.1
13W 31N 18.3
13W 32N 17.5
14.5W 30.5N 19
14.5W 30N 19.3
14.5W 31.5N 18.7
14.5W 31N 18.8
14.5W 32N 18.5
14W 30.5N 19
14W 30N 19.2
14W 31.5N 18.7
14W 31N 18.7
14W 32N 18.6
15W 30.5N 19.1
15W 30N 19.3
15W 31.5N 18.9
15W 31N 18.9
15W 32N 18.6
>