我有三个包含相同对象不同数据的csv文件。这些代表有关工作项的不同集合的数据。这些对象具有唯一的代码。文件的数量并不重要,因此我将设置两个问题。我有一个方便的秘诀,可以使用join
来加入这些文件,但是清理部分正在杀死我。
文件片段-包含唯一数据。还有编目错误E B
。
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 ...等等。”我全是耳朵。没有规则,我只需要交付即可!
答案 0 :(得分:4)
您的问题是说数据是csv,但根据您的样本,我假设它是tsv。我还假设E B
应该出现在异常输出中,并且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
答案 1 :(得分:1)
尝试一下(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
。