【发布时间】:2018-12-26 16:09:52
【问题描述】:
我有一些数据文件,我想为其生成一个“差异”列,这意味着添加一个列来指示是否从当前文件中添加/删除了特定行。比如我有以下两个文件,a.csv:
id,data,data2
1,A,B
2,A,B
3,A,B
4,A,B
和b.csv:
id,data,data2
2,A,C
3,A,C
4,A,C
5,A,C
我只想根据id 比较是否添加/删除了一行。数据无所谓。到目前为止,我想出的最好方法是以以下方式使用miller:
#!/bin/bash
t1=$(mktemp)
t2=$(mktemp)
t3=$(mktemp)
mlr --icsv --ocsv put '$diff = "-"' then reorder -f diff a.csv > "$t1"
mlr --icsv --ocsv put '$diff = "+"' then reorder -f diff b.csv > "$t2"
mlr --icsv --ocsv join -f "$t1" -j id --ul --ur --np then unsparsify "$t2" > "$t3"
mlr --icsv --ocsv join -f "$t3" -j id --ul --ur then unsparsify then reorder -f diff,id then sort -nf id b.csv
rm "$t1"
rm "$t2"
rm "$t3"
这会生成以下内容,这就是我想要的:
diff,id,data,data2
-,1,A,B
,2,A,C
,3,A,C
,4,A,C
+,5,A,C
这个解决方案的不幸之处在于它需要运行 miller 四次并使用三个临时文件。 Miller 似乎不适用于 bash 进程替换(<() 业务)。
有没有更直接的方法来生成这种输出?
【问题讨论】:
-
您可以在每个文件上
cut -f1 -d',',然后通过管道传送到diff? -
@jeremysprofile 谢谢,但我最终不会得到需要进一步处理的 CSV 输出文件。
-
join获取单个文件中的所有数据,awk进行比较并写入所需的格式? -
@Poshi 这将导致更少的调用,但它基本上会导致我编写一个程序来执行它,然后我可以用任何语言执行它。我一直在寻找一种可以轻松完成的工具。
-
你是对的。但是,当代码如此简单且工具不存在时,使用可用的东西可能是矫枉过正,就像这种情况一样。实际上,通过使用 miller,您也是在自己编写程序:您是在告诉 miller 执行大量有序操作。