Sam*_*ami 2 command-line awk text-processing
我有两组数据。我想通过两个键值(storm_ID、Cell_ID)加入它们。
第一个数据集看起来像:
Storm_ID,Cell_ID,Wind_speed
2,10236258,27
2,10236300,58
2,10236301,25
3,10240400,51
Run Code Online (Sandbox Code Playgroud)
第二个数据集看起来像:
Storm_ID,Cell_ID,Storm_surge
2,10236299,0.27
2,10236300,0.27
2,10236301,0.35
2,10240400,0.35
2,10240401,0.81
4,10240402,0.11
Run Code Online (Sandbox Code Playgroud)
现在我想要一个看起来像这样的输出:
Storm_ID,Cell_ID,Wind_speed,Storm_surge
2,10236258,27,0
2,10236299,0,0.27
2,10236300,58,0.27
2,10236301,25,0.35
2,10240400,0,0.35
2,10240401,0,0.81
3,10240400,51,0
4,10240402,0,0.11
Run Code Online (Sandbox Code Playgroud)
我尝试在 Linux 中使用 join 命令来执行此任务,但失败了。Join 命令跳过了数据库中不匹配的行。我可以使用 Matlab,但数据大小超过 100 GB,这使得这项任务非常困难。有人可以请指导我吗?我可以使用 SQL 或 python 来完成这个任务。
使用 awk 和排序:
awk -F, -v OFS=, '{x = $1 "," $2} FNR == NR {a[x] = $3; b[x] = 0; next} {b[x] = $3} !a[x] {a[x] = 0} END {for (i in a) print i, a[i], b[i]}' f1 f2 | sort -n
Run Code Online (Sandbox Code Playgroud)
-F, -v OFS=, - 将输入和输出设置为分隔 ,{x = $1 "," $2}保存由 分隔的前两个字段,,因为组合是公共索引。FNR == NR {a[x] = $3; b[x] = 0; next}-FNR是每个文件的记录编号,NR是跨文件的总记录编号。这些对于第一个文件是相等的,所以这个块只对第一个文件运行。在这里,我将第一个文件的第三列保存在数组中a,并将对应的条目初始化b为0。然后我跳到下一条记录。{b[x] = $3} !a[x] {a[x] = 0}- 这两个是针对第二个文件运行的,将第三列保存在 中b,如果 中没有相应的条目a,则将其设置为 0。END {for (i in a) print i, a[i], b[i]}, 在两个文件的末尾,打印到目前为止获得的每条记录由于在 awk 中循环数组会给出随机顺序,因此我们需要在最后对输出进行排序sort -n:
$ awk -F, -v OFS=, '{x = $1 "," $2} FNR == NR {a[x] = $3; b[x] = 0; next} {b[x] = $3} !a[x] {a[x] = 0} END {for (i in a) print i, a[i], b[i]}' f1 f2 | sort -n
Storm_ID,Cell_ID,Wind_speed,Storm_surge
2,10236258,27,0
2,10236299,0,0.27
2,10236300,58,0.27
2,10236301,25,0.35
2,10240400,0,0.35
2,10240401,0,0.81
3,10240400,51,0
4,10240402,0,0.11
Run Code Online (Sandbox Code Playgroud)