如何选择、复制不同文件的列以形成新文件

如何选择、复制不同文件的列以形成新文件

我有四个文件,每个文件都包含每日站点数据。

  • 文件1:prec
  • 文件2:minT
  • 文件3:最大T
  • 文件4:风

这里 prec、minT、maxT 和 Wind 是存储站点 1 到 n 的 prec、minT、maxT 和 Wind 值的文件。

我想存储每个站的数据,例如:

for station 1: prec minT maxT wind 
    station 2: prec minT maxT wind
    .
    .
    .
    .
    station n: prec minT maxT wind

编辑#1

我的四个数据如下所示:

普雷克

1        2        3        4        5        6        7        8
0        0        0        0        0        0        0        0
0.254        0.254        0.254        0.254        0.254        0.254        0.254        0.254
0        0        0        0        0        0        0        0

最小温度

1          2          3          4          5          6          7          8
-23.349        -23.339        -23.327        -23.316        -23.303        -23.291        -23.278        -23.266
-23.682        -23.683        -23.685        -23.687        -23.689        -23.692        -23.695        -23.698
-24.302        -24.301        -24.3        -24.299        -24.299        -24.299        -24.3        -24.302

最高温度

 1         2         3         4         5         6         7         8
-17.087        -17.082        -17.077        -17.072        -17.066        -17.06        -17.053        -17.046
-20.082        -20.095        -20.109        -20.124        -20.14        -20.157        -20.174        -20.191
-20.48        -20.481        -20.483        -20.485        -20.486        -20.488        -20.489        -20.49

1        2        3        4        5        6        7        8
0        0        0        0        0        0        0        0
1.778        1.778        1.778        1.778        1.778        1.778        1.778        1.778
1.652        1.653        1.654        1.654        1.655        1.656        1.657        1.658

我想为每个命名点(即点 1 到 8)格式化数据文件,如下所示:

1

0        -23.349        -17.087        0
0.254        -23.682        -20.082        0
0        -24.302        -20.48        1.778

2

0        -23.339        -17.082        0
0.254      -23.683        -20.095        0
0        -24.301        -20.481        1.778

...等等...到n

每个文件中的列为:nprecnTminnTmaxnwind

答案1

我认为你可以用paste, 并且可能 来做到这一点join

paste file1 file2 > temp1
paste temp1 file3 > temp2
paste tmpe2 file4 > final

如果文件按顺序包含站 1 到站数据,那么这应该可以工作。如果没有,您将需要以某种方式对齐文件。如果“station n”符号是每个文件的一部分,您应该对它们进行排序:

sort -o file1 file1
sort -o file2 file2
... and so forth

然后,你可以这样做join而不是paste像上面那样。join有一些棘手的选项,用于将与其他文件中不匹配的行放入输出中,因此您可能必须join非常仔细地阅读手册页并进行一些实验才能获得您想要的内容。

答案2

从您的描述来看,您似乎想要迭代 4 个文件(Prec、Tmin、Tmax 和 Wind),并从每个文件中获取列数据,并将其合并到每个列的单个文件中。

该方法

实现此目的的一种方法是使用 Bashfor循环,paste并且awk.该方法将是这样的:

for i in `seq 8`; do
    ... do stuff ...
done

此循环的主要目的是逐步执行第 1 列到第 8 列。

拉出列

我们需要组合的下一个功能是从文件中按列提取数据的能力。一个想法是使用awk来做到这一点。

$ awk '{print $1}' Prec
1
0
0.254
0

我们可以更进一步,让它跳过第一行,这是列的参考号,如下所示:

$ awk 'NR>1{print $1}' Prec
0
0.254
0

我们可以更进一步,通过参数化我们正在打印的列,使其成为我们传递给的变量,awk如下所示:

$ awk -v a=1 'NR>1{print $a}' wind
0
1.778
1.652
$ awk -v a=2 'NR>1{print $a}' wind
0
1.778
1.653

从多个文件中提取列

这一点可能是这个解决方案中最不优雅的一点,但我是一个awk菜鸟,所以当有疑问时,请尝试一下。

这里使用多个 的输出,awk这些输出从每个文件中提取按列的数据,并使用 将它们粘贴在一起paste

这是其中 2 个文件,以便更容易查看。

第 1 栏

$ paste <(awk -v a=1 'NR>1 {print $a}' Prec) <(awk -v a=1 'NR>1 {print $a}' Tmin)
0   -23.349
0.254   -23.682
0   -24.302

第 2 栏

$ paste <(awk -v a=2 'NR>1 {print $a}' Prec) <(awk -v a=2 'NR>1 {print $a}' Tmin)
0   -23.339
0.254   -23.683
0   -24.301

为了从所有 4 个文件中获取列,我们将简单地扩展此方法。

将我们的索引 ( $i) 设置为 1。

$ i=1
$ paste <(awk -v a=$i 'NR>1 {print $a}' Prec) <(awk -v a=$i 'NR>1 {print $a}' Tmin) <(awk -v a=$i 'NR>1{print $a}' Tmax) <(awk -v a=$i 'NR>1 {print $a}' wind)
0   -23.349 -17.087 0
0.254   -23.682 -20.082 1.778
0   -24.302 -20.48  1.652

将索引 ( $i) 设置为 2。

$ i=2
$ paste <(awk -v a=$i 'NR>1 {print $a}' Prec) <(awk -v a=$i 'NR>1 {print $a}' Tmin) <(awk -v a=$i 'NR>1{print $a}' Tmax) <(awk -v a=$i 'NR>1 {print $a}' wind)
0   -23.339 -17.082 0
0.254   -23.683 -20.095 1.778
0   -24.301 -20.481 1.653

把它们放在一起

现在让我们将 合并到循环paste <(awk ..) <(awk ..) <(awk ..) <(awk ..)for

$ for i in `seq 8`; do 
  echo "## $i ##"
  paste <(awk -v a=$i 'NR>1 {print $a}' Prec) <(awk -v a=$i 'NR>1 {print $a}' Tmin) <(awk -v a=$i 'NR>1{print $a}' Tmax) <(awk -v a=$i 'NR>1 {print $a}' wind)
done
## 1 ##
0   -23.349 -17.087 0
0.254   -23.682 -20.082 1.778
0   -24.302 -20.48  1.652
## 2 ##
0   -23.339 -17.082 0
0.254   -23.683 -20.095 1.778
0   -24.301 -20.481 1.653
## 3 ##
0   -23.327 -17.077 0
0.254   -23.685 -20.109 1.778
0   -24.3   -20.483 1.654
...

我在上面添加了一个额外的内容echo,以便在输出中更容易看到正在打印哪一列。

将所有内容写入文件

通过在命令后面添加该位paste ...,我们可以将结果写入您指定的各个文件中。

paste ... | tee out$i.txt

整个事情就像一条线:

$ for i in `seq 8`;do echo "## $i ##"; paste <(awk -v a=$i 'NR>1 {print $a}' Prec) <(awk -v a=$i 'NR>1 {print $a}' Tmin) <(awk -v a=$i 'NR>1{print $a}' Tmax) <(awk -v a=$i 'NR>1 {print $a}' wind) | tee out$i.txt;done

这会导致这些文件被写入:

$ ll
total 48
-rw-rw-r-- 1 saml saml  71 Aug 21 23:17 out1.txt
-rw-rw-r-- 1 saml saml  72 Aug 21 23:17 out2.txt
-rw-rw-r-- 1 saml saml  70 Aug 21 23:17 out3.txt
-rw-rw-r-- 1 saml saml  72 Aug 21 23:17 out4.txt
-rw-rw-r-- 1 saml saml  71 Aug 21 23:17 out5.txt
-rw-rw-r-- 1 saml saml  71 Aug 21 23:17 out6.txt
-rw-rw-r-- 1 saml saml  70 Aug 21 23:17 out7.txt
-rw-rw-r-- 1 saml saml  71 Aug 21 23:17 out8.txt

相关内容