【问题标题】:Keep first duplicate and replace the rest with blank cell using Awk [closed]使用 Awk 保留第一个副本并用空白单元格替换其余部分 [关闭]
【发布时间】:2018-10-10 11:07:44
【问题描述】:

我有一个 tsv 文件,其中有 2 列,第二列中有重复项。我想做的是保留第一个重复值并将其余的替换为空白。例如

原始tsv:

ahah.asd   aha
ahsjd.asd  aha
asdd.asda  aha
ajd.asd    aha
asdfk.lo   abb
hasd.pou   abb
hasd.asd   jjj
asidh.09   kkk
asdhs.97   kkk

预期输出:

ahah.asd   aha
ahsjd.asd  
asdd.asda  
ajd.asd    
asdfk.lo   abb
hasd.pou   
hasd.asd   jjj
asidh.09   kkk
asdhs.97   

除此之外,我想添加一个递增的列,直到在第 2 列中看到重复项。例如:

ahah.asd   aha   1
ahsjd.asd        2
asdd.asda        3
ajd.asd          4
asdfk.lo   abb   1
hasd.pou         2
hasd.asd   jjj   1
asidh.09   kkk   1 
asdhs.97         2

这可能吗?我想用awk...

谢谢

【问题讨论】:

  • 重复值是否总是在连续的行上?

标签: linux bash csv awk


【解决方案1】:
$ awk 'BEGIN{FS=OFS="\t"} {print $1, (cnt[$2]++ ? "" : $2), cnt[$2]}' file
ahah.asd        aha     1
ahsjd.asd               2
asdd.asda               3
ajd.asd         4
asdfk.lo        abb     1
hasd.pou                2
hasd.asd        jjj     1
asidh.09        kkk     1
asdhs.97                2

【讨论】:

    【解决方案2】:

    试试这个:

    $ awk -v OFS='\t' 's!=$2{c=0;s=$2}{print $1,(c++?"":s),c}' file
    ahah.asd    aha 1
    ahsjd.asd       2
    asdd.asda       3
    ajd.asd     4
    asdfk.lo    abb 1
    hasd.pou        2
    hasd.asd    jjj 1
    asidh.09    kkk 1
    asdhs.97        2
    

    每个字段之间有一个选项卡。

    【讨论】:

    • 这非常好用!
    • c++==0?s:"" = c++?"":s。此外,在某些情况下,没有括号的三元表达式会在某些 awk 中导致语法错误,因此我总是使用括号来避免该问题并提高可读性:print $1, (c++?"":s), c
    • @EdMorton 没有父级的三元表达式在哪里导致语法错误? (这听起来更像是我的错误。)但我喜欢c++?"":s :-)
    • 找到面包屑:请注意stackoverflow.com/questions/15887368/… 处的评论及其下方的回复,这不是 100% 正确的,因为只需添加括号即可解决问题。
    • 显然printf "%s ",NR==3?$1:"\n"$1 导致了该语法错误。在这里,我肯定会加上括号,因为$1 是否属于三元运算并不是立即可以理解的。如果它看起来很明确,我通常不会。谢谢!
    【解决方案3】:

    您可以使用awkcolumn

    awk '{print $1,(($2 in a)?"":$2),++a[$2]}' OFS=, file | column -t -s,
    

    【讨论】:

      【解决方案4】:

      便携式 Perl 解决方案

      $ perl -F'\s+' -lane ' { $p=$x{$F[1]}++;$k=$p==0?$F[1]:""; print "$F[0]\t$k\t",$p+1 } ' tsv_file
      ahah.asd        aha     1
      ahsjd.asd               2
      asdd.asda               3
      ajd.asd         4
      asdfk.lo        abb     1
      hasd.pou                2
      hasd.asd        jjj     1
      asidh.09        kkk     1
      asdhs.97                2
      

      更紧凑:

      $ perl -F'\s+' -lane ' { $p=$x{$F[1]}++==0?$F[1]:""; print "$F[0]\t$p\t",$x{$F[1]} } ' tsv_file
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-07
        • 2017-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多