使用awk将矩阵转换为值对

时间:2013-01-27 19:53:59

标签: awk

我有一个纬度经度和温度的数据矩阵,格式如下:

            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,因为我已经用它做了一些其他事情并且它非常强大。但也许在这里可以使用其他一些工具。

行数和列数并不总是相同。

我还需要将纬度和经度转换为十进制分钟,但我一步一步。

3 个答案:

答案 0 :(得分:3)

awk one-liner(也许有点长):

 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
>