【问题标题】:bash: grep row if fields are equalbash:如果字段相等,则 grep 行
【发布时间】:2021-02-09 21:40:06
【问题描述】:

我需要通过检查系统中的所有 CSV 文件来查找所有列中具有相同内容的所有行。示例:

MYCOL;1;2;3;4
MYCOL2;2;3;4;5
MYCOL3;1;1;1;1
MYCOL4;;;;

在我的示例中,我需要对 MYCOL3 和 MYCOL4 进行 grep,因为它们对于所有列都有相同的字段内容,如果没有内容也没关系。

我想过这样的事情:

find / -name *.csv | xargs awk -F "," '{col[$1,$2]++} END {for(i in col) print i, col[i]}'

但我错过了所有列之间的比较。

【问题讨论】:

    标签: regex awk find cut


    【解决方案1】:

    您可以使用grep 命令:

    $ grep -xE '[^;]*(;[^;]*)\1+' ip.txt
    MYCOL3;1;1;1;1
    MYCOL4;;;;
    
    • -x 只匹配整行
    • [^;]* 第一个字段
    • (;[^;]*) 捕获 ; 后跟非 ; 字符(即第二个字段)
    • \1+ 使用捕获的字段根据需要重复多次,直到行尾

    如果输入只有 ASCII 字符,您可以使用LC_ALL=C grep <...> 更快地获得结果。

    如果你有GNU grep,你可以使用-r选项和--include=选项代替find+grep

    另外,使用find <...> -exec grep <...> {} + 而不是find + xargs


    刚刚做了一个示例速度检查,这个正则表达式可能太糟糕了,无法与 BRE/ERE 一起使用。如果可用,请使用grep -P。否则,请使用awkperl

    $ perl -0777 -ne 'print $_ x 1000000' ip.txt | shuf > f1
    $ du -h f1
    53M    f1
    
    $ time LC_ALL=C grep -xE '[^;]*(;[^;]*)\1+' f1 > t1
    real    0m44.815s
    
    $ time LC_ALL=C grep -xP '[^;]*(;[^;]*)\1+' f1 > t2
    real    0m0.507s
    
    $ time perl -ne 'print if /^[^;]*(;[^;]*)\1+$/' f1 > t3
    real    0m3.973s
    
    $ time LC_ALL=C awk -F ';' '{for (i=3; i<=NF; i++) if ($i != $2) next} 1' f1 > t4
    real    0m2.728s
    
    $ diff -sq t1 t2
    Files t1 and t2 are identical
    $ diff -sq t1 t3
    Files t1 and t3 are identical
    $ diff -sq t1 t4
    Files t1 and t4 are identical
    

    【讨论】:

      【解决方案2】:

      使用awk 的非正则表达式方法:

      awk -F ';' '{for (i=3; i<=NF; i++) if ($i != $2) next} 1' file
      
      MYCOL3;1;1;1;1
      MYCOL4;;;;
      

      【讨论】:

        【解决方案3】:

        另一个 awk

        $ awk -F";" -v OFS=";" ' { a=$0; $1=""; c=split($0,ar,$2); if(length($0)==NF-1 || c==NF) print a } ' gipsy.txt
        MYCOL3;1;1;1;1
        MYCOL4;;;;
        $
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-31
          • 1970-01-01
          • 2018-08-05
          • 1970-01-01
          • 2018-05-21
          相关资源
          最近更新 更多