如果所有列中的值相同,则删除行

时间:2018-10-09 14:51:38

标签: awk duplicates

我有一个用空格分隔的大文件,其中包含成千上万的行和列。我想删除除第一列外所有列中具有相同值的所有行。

输入:

CHROM   108 139 159 265 350 351
SNP1    -1  -1  -1  -1  -1  -1
SNP2    2   2   2   2   2   2
SNP3    0   0   0   -1  -1  -1
SNP4    1   1   1   1   1   1
SNP5    0   0   0   0   0   0

所需

CHROM   108 139 159 265 350 351
SNP3    0   0   0   -1  -1  -1

对于Panda Framework(Delete duplicate rows with the same value in all columns in pandas),有一个类似的问题,我发现了一种较为局部的解决方案,可以删除仅包含零行的行

awk 'NR > 1{s=0; for (i=3;i<=NF;i++) s+=$i; if (s!=0)print}' input > outfile

但是我想对数字-1、0、1和2进行一次,标题和第一列作为标识符。

我们将不胜感激任何帮助。

4 个答案:

答案 0 :(得分:2)

我相信您可以执行以下操作:

result = out.split('\n')

哪个输出:

awk '{s=$0; gsub(FS $2,FS)} (NF > 1) {print s}' file

这是如何工作的?

  1. CHROM 108 139 159 265 350 351 SNP3 0 0 0 -1 -1 -1 此操作包含2个部分:

    • 将当前行存储在变量{s=$0; gsub(FS $2,FS)}
    • 在当前行s中用字段分隔符$0替换第二个字段的所有值,包括第二个字段的起始字段分隔符FSFS $2)。这样做的副作用是重新定义FS,并且重新定义所有字段变量和字段$0的总数。如果NF
    • ,则需要使用字段分隔符FS来避免与xx匹配
  2. $2=x:如果剩下的字段还剩1个,则打印该行,这意味着您拥有各种数字。

答案 1 :(得分:1)

请您尝试以下。

awk '{val=$2;count=1;for(i=3;i<=NF;i++){if(val==$i){count++}};if(count!=(NF-1)){print}}'  Input_file

答案 2 :(得分:1)

您可以尝试以下方法:

awk 'NR==1;NR>1{for(i=2;i<NF;i++)if($(i+1)!=$i) {print;next}}' file

打印标题行。
它会遍历各个字段,直到找到与下一个字段的区别,然后打印并转到下一个字段。

答案 3 :(得分:0)

便携式Perl解决方案:

$ cat all_row
CHROM   108 139 159 265 350 351
SNP1    -1  -1  -1  -1  -1  -1
SNP2    2   2   2   2   2   2
SNP3    0   0   0   -1  -1  -1
SNP4    1   1   1   1   1   1
SNP5    0   0   0   0   0   0

$ perl -F"\s+" -ane ' { print "$_" if @F[1 .. $#F-1] != $F[1] } ' all_row
CHROM   108 139 159 265 350 351
SNP3    0   0   0   -1  -1  -1

$

如果要问的是不要在所有列中都删除相同的值,则

$ perl -F"\s+" -ane ' { print "$_" if @F[1 .. $#F-1] == $F[1] } ' all_row
SNP1    -1  -1  -1  -1  -1  -1
SNP2    2   2   2   2   2   2
SNP4    1   1   1   1   1   1
SNP5    0   0   0   0   0   0