代码之家  ›  专栏  ›  技术社区  ›  Rasec Malkic

如何根据第1列和第3列中的条件删除重复项?

  •  1
  • Rasec Malkic  · 技术社区  · 1 年前

    我正试图从一个大的csv文件中删除重复项,基于第1列中的con值,但考虑到这一点:

    第3列可以为空,也可以有多个由分隔的值 ::: 如果第1列中有多个重复值,请保留第3列中元素数最多的记录。 删除 - 在第3列中的数字之间(如果存在)。

    我的输入是:

    H1,H2,H3,H4
    a,2,8005:::+2287:::3426,2
    b,4,1111:::+15-00:::01354,1
    b,4,1111:::+1500,1
    c,4,2208:::+6583,9
    d,5,7761:::+993733:::+53426,4
    d,5,7761:::+993-733:::+53-426:::87425,4
    d,5,7761:::53-426,4
    

    我试图得到的结果是:

    H1,H2,H3,H4
    a,2,8005:::+2287:::3426,2
    b,4,1111:::+1500:::01354,1
    c,4,2208:::+6583,9
    d,5,7761:::+993733:::+53426:::87425,4
    

    我当前的脚本只删除重复项而不考虑其他因素,因为我不知道如何混合两个脚本以及如何添加 条件以保留第3列中包含更多元素的记录。

    awk -F, '{ gsub(/-/,"", $3); print } ' input.csv > input_without_hyphen.csv
    awk -F',' -v OFS=',' '!a[$1]++' input_without_hyphen.csv > output.csv
    

    谢谢你的帮助。

    1 回复  |  直到 1 年前
        1
  •  2
  •   markp-fuso    1 年前

    假设:

    • 逗号只显示为分隔符(即,我们不必担心逗号会显示在实际数据中)
    • 如果2行 完全相同 并且在第三列中有相同数量的元素,然后我们保留我们处理的第一个
    • 要维持输入顺序

    awk 主意

    awk '
    BEGIN  { FS = OFS = "," }
    
    FNR==1 { print; next }              # print header as is
    
           { key = $1                   # define key for this row
             if (! (key in counts))     # if we have not seen this key before then ...
                order[++ordnum] = key   # associate the key with the next ordering number
    
             gsub(/-/,"",$3)            # remove all hyphens from 3rd column
    
             n = split($3,a,/:::/)      # split 3rd column on ":::" delimiter, store results in array a[]; "n" == number of elements in array
    
             if (n > counts[key]) {     # if the number of elements (in 3rd column) is more than the previous count (for a row with the same key) then ...
                counts[key] = n         # save the new count and ...
                rows[key]   = $0        # save the current row
             }
           }
    
    END    { for (i=1; i<=ordnum; i++)  # iterate through our ordering numbers and ...
                print rows[order[i]]    # print the associated row to stdout
           }
    ' input.csv
    

    这会产生:

    H1,H2,H3,H4
    a,2,8005:::+2287:::3426,2
    b,4,1111:::+1500:::01354,1
    c,4,2208:::+6583,9
    d,5,7761:::+993733:::+53426:::87425,4
    

    注意: 虽然数据的顺序与OP的预期输出相同,但排序并不总是有保证的;如果行顺序很重要,那么我们需要添加更多的代码