【问题标题】:AWK - use column value from input to create new columns on outputAWK - 使用输入中的列值在输出中创建新列
【发布时间】:2017-11-10 11:52:27
【问题描述】:

我有一个这样的文件:

       Date     Time   Level Gridsize    Miss      Temp    Parameter ID
 1988-05-16 12:00:00      -3        1       0     27.060    -1            
 1988-05-16 12:00:00      -3        1       0     9.0300    -2            
 1988-05-16 12:00:00      -3        1       0     1.2000    -3            
 1988-05-17 12:00:00      -3        1       0     27.100    -1            
 1988-05-17 12:00:00      -3        1       0     9.0200    -2            
 1988-05-17 12:00:00      -3        1       0     1.2300    -3            
 1988-05-18 12:00:00      -3        1       0     27.190    -1            
 1988-05-18 12:00:00      -3        1       0     9.0400    -2            
 1988-05-18 12:00:00      -3        1       0     1.2200    -3            

这些是来自不同位置的传感器的温度数据。字段Parameter ID 确定数据是从传感器-1、-2 还是-3 获取的。我正在将此数据导出到 CSV 文件以进行分析。所需的格式是:

   Date     Time           -1       -2        -3    
1988-05-16 12:00:00      27.060    9.0300    1.2000                     
1988-05-17 12:00:00      27.100    9.0200    1.2300
1988-05-18 12:00:00      27.190    9.0400    1.2200   

它按日期时间对数据进行分组,并根据Parameter ID 的值按列分隔。

我不确定 AWK 的可行性如何,但我曾经主要使用 SSH 来准备这些数据,使用 AWK 的解决方案对我来说非常有趣。另外,如果有其他工具可以在 bash 上实现这一点,我很感兴趣 :)(sed,无论如何,但必须使用本机 linux 命令,因为我不允许在服务器上安装任何东西)


我现在在做什么

现在我为每个传感器运行一个代码

$ awk '$NF == "-1" {print $1";"$2";"$6}' > netcdf_extract_1.csv
$ awk '$NF == "-2" {print $1";"$2";"$6}' > netcdf_extract_2.csv
$ awk '$NF == "-3" {print $1";"$2";"$6}' > netcdf_extract_3.csv

然后在 python 上导入它们。然后我按日期和时间对它们进行分组并得到我的桌子。

【问题讨论】:

  • 你尝试过什么吗?
  • 好吧,现在我得到了 3 个文件,每个传感器一个,并在 python 上加入它们。另外,我尝试了一些东西。我会发布代码。

标签: linux bash awk


【解决方案1】:

GNU awk 解决方案:

awk 'BEGIN{ PROCINFO["sorted_in"]="@ind_str_asc"; }
     NR > 1{ a[$1"\t"$2][$7]=$6 }
     END{ 
         printf "Date\tTime\t-1\t-2\t-3\n"; 
         for (i in a) print i,a[i][-1],a[i][-2],a[i][-3] 
     }' file | column -t
  • a[$1"\t"$2][$7]=$6
    • a - 多维数组
    • $1"\t"$2 - 由日期/时间字段串联构造的数组键/索引
    • [$7] - 以参数 ID 字段值
    • 索引的内部数组
    • $6 - Temp 字段中的关键值

输出:

Date        Time      -1      -2      -3
1988-05-16  12:00:00  27.060  9.0300  1.2000
1988-05-17  12:00:00  27.100  9.0200  1.2300
1988-05-18  12:00:00  27.190  9.0400  1.2200

【讨论】:

  • 在 ubuntu 17.04 上运行时出现错误:awk: line 2: syntax error at or near [ awk: line 5: syntax error at or near [ 任何线索?
  • @rvbarreto,检查您是否正确复制/粘贴。效果很好,看截图ibb.co/jKqVLw
  • 我可能会让一些事情落后。只是做了同样的事情并得到了错误,https://ibb.co/cuNS0w
  • @rvbarreto,我的第一句话清楚地说是 GNU awk。这是主要条件。
  • 好的,我发现了问题。对于在 v4 之前使用 awk 或 gawk 的人,不支持真正的多数组。在这种情况下,您必须使用关联数组:awk 'BEGIN { PROCINFO["sorted_in"]="@ind_str_asc"; } NR > 1 {a[$1"\t"$2,$7]=$6; if($NF==-1){b[$1"\t"$2]=$6}} END{printf "Date\tTime\t-1\t-2\t-3\n"; for (i in b){print i, a[i,-1],a[i,-2],a[i,-3]}}'
【解决方案2】:

这是我的尝试:

awk 'BEGIN{print "Date\t","Time\t", "-1\t", "-2\t", "-3\t";
    PROCINFO["sorted_in"] = "@ind_str_asc" }
    NR > 1{ a[$1] = a[$1]" " $6 ; b[$1] = $2;next }
    END{ for ( i in a ) print i, b[i], a[i] }' file1 | column -t

输出:

Date        Time      -1      -2      -3
1988-05-16  12:00:00  27.060  9.0300  1.2000
1988-05-17  12:00:00  27.100  9.0200  1.2300
1988-05-18  12:00:00  27.190  9.0400  1.2200

由于 Roman 在一个数组中包含所有内容,因此我将任务拆分为两个数组。

【讨论】:

  • 不错!它类似于我在 Roman 的解决方案上发布的代码,但更优雅!谢谢!
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 2021-08-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 2015-08-21
  • 1970-01-01
  • 2021-12-15
相关资源
最近更新 更多