如何使用awk匹配两个CSV文件?

如何使用awk匹配两个CSV文件?

我有两个 CSV 文件

ID1,V1,V2,V3,V4
1,4,5,3,3
2,66,77,46,44
3,66,77,46,44

ID2,V1,V2,V3,V4
55,4,5,3,3
84,66,77,46,44

我如何获得 CSV

ID1,ID2
1,55
2,84
3,84

通过匹配V1,V2,V3,V4两个 CSV 文件中的块?

目的是file1通过替换V1,V2,V3,V4中相应的ID2值来重现file2。换句话说,result文件中的行数与file1.

ID1并且ID2是独特且有序的,ID1,ID2也将是独特的。文件格式正确。仅,显示五列中用分隔符分隔的数字。

这些文件非常大(1B 行),这就是我需要像awk.

给出的解决方案这里应该适用,但它是相反的连接(通用ID),我无法将其适应我的情况。

答案1

以下内容将很快,并且只有该sort部分在内存中存储任何大量数据,并且它是为执行分页等而构建的。处理该问题,因此应该没问题:

$ cat tst.sh
#!/usr/bin/env bash

# First awk output is hdrFlag,fileNr,ID,VALs1-4 then we sort on
# the hdrFlag to handle the header line first, then the key values
# so we can process all matching keys together from both input
# files so we only have to store the IDs for the current key set.
awk 'BEGIN{FS=OFS=","} FNR==1{++fileNr} {print (FNR>1), fileNr, $0}' "$@" |
sort -t, -k1,1n -k4 |
awk '
    BEGIN { FS=OFS="," }
    {
        curr = $4 FS $5 FS $6 FS $7
        if ( curr != prev ) {
            prt()
            prev = curr
        }
        ids[$2] = ($2 in ids ? ids[$2] " " : "") $3
    }
    END { prt() }

    function prt(       file,numFiles) {
        for (file in ids) {
            numFiles++
        }
        if (numFiles > 1) {
            print ids[1], ids[2]
        }
        delete ids
    }
'

$ ./tst.sh file1 file2
ID1,ID2
1,55
2,84

我只是猜测您希望如何处理文件之间对于同一组 4 个值存在多个匹配的情况。

相关内容