[英]bash: clean and merge data
我有三个包含相同对象不同数据的csv文件。 这些代表有关工作项的不同集合的数据。 这些对象具有唯一的代码。 文件的数量并不重要,因此我将设置两个问题。 我有一个方便的方法可以使用join
来加入这些文件-但是清理部分使我丧命。
文件片段-包含唯一数据。 还有编目错误EB
。
B 547
J 65
EB 289
E B 1
CO 8900
ZX 7
文件B片段-有关对象不同维度的唯一数据。
B 5
ZX 67
SD 4
CO 76
J 54
EB 10
请注意,文件B包含与文件A不同的代码。
现在,我向您提交为这组对象指定的“官方”代码规范:
B
CO
ZX
J
EB
请注意,文件B包含带有数据的非规范代码。 需要对其进行捕获和记录。 与文件A中的错误代码相同。
最终目标:使用多个报告中的各个字段对集合运行趋势和统计信息。 它们大都与经典匹配,但由于编目错误和不再使用的代码而存在奇怪的情况。
合并/加入后的最终目标结果:
B 547 5
J 65 54
EB 289 10
CO 8900 76
ZX 7 67
所以我的第一个想法是为此使用grep -F -f
,使用规范代码作为搜索列表,然后与join
合并。 问题是,一个字母代码太包容了。 这似乎是awk
的工作,它可以与tab
符分隔符和REGEX
奇数代码一起使用。 我不确定,但是,如何获取awk
以使用列表筛选其他文件。 单独join
会处理所有这一切吗? 也许我合并join
或paste
,然后筛选出古怪的人? 哪一种方法最不易碎,并且最有可能处理如醉酒分类器这样的边缘情况?
如果您在想,“老兄,最好用Perl或Python ...等等。” 我全是耳朵。 没有规则,我只需要交付即可!
您的问题说数据是csv,但是根据您的样本,我假设它是tsv。 我还假设EB
应该在异常输出中结束,并且NA值应该用0
填充。
鉴于这些假设,以下可能就足够了:
sort -t $'\t' -k 1b,1 fileA > fileA.sorted && sort -t $'\t' -k 1b,1 fileB > fileB.sorted
join -t $'\t' -a1 -a2 -e0 -o auto fileA.sorted fileB.sorted > out
grep -f codes out > out-canon
grep -vf codes out > out-oddball
文件codes
的内容:
^B\s
^CO\s
^ZX\s
^J\s
^EB\s
结果:
$ cat out-canon B 547 5 CO 8900 76 EB 289 10 J 65 54 ZX 7 67 $ cat out-oddball E B 1 0 SD 0 4
试试这个(GNU awk):
awk 'BEGIN{FS=OFS="\t";}ARGIND==1{c[$1]++;}ARGIND==2{b[$1]=$2}ARGIND==3{if (c[$1]) {print $1,$2,b[$1]+0; delete b[$1];} else {if(tolower($1)~"[a-z]+ +[a-z]+")print>"error.fileA"; else print>"oddball.fileA";}}END{for (i in b) {print i,0,b[i] " (? maybe?)";print i,b[i] > "oddball.fileB";}}' codes fileB fileA
如果存在这样的行,它将创建error.fileA
, oddball.fileA
, oddball.fileB
。
正常输出未写入文件,结果正常时,您可以使用>
自己编写:
B 547 5
J 65 54
EB 289 10
CO 8900 76
ZX 7 67
SD 0 4 (? maybe?)
很难阅读您的描述,不确定这是否是您想要的。
无论如何,改进此awk代码很容易。
您可以更改为FILENAME=="file1"
或FILENAME==ARGV[1]
如果ARGIND
不起作用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.