如果所有列中的值相同,则删除行
Posted
技术标签:
【中文标题】如果所有列中的值相同,则删除行【英文标题】:Delete row if same value in all columns 【发布时间】:2018-10-09 14:51:37 【问题描述】:我有一个包含数千行和列的以空格分隔的大文件。我想删除除第一列之外的所有列中具有相同值的所有行。
输入:
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 框架 (Delete duplicate rows with the same value in all columns in pandas) 提出了类似的问题,我找到了一个部分解决方案,它删除了仅包含零的行
awk 'NR > 1s=0; for (i=3;i<=NF;i++) s+=$i; if (s!=0)print' input > outfile
但我想一次性对数字 -1、0、1 和 2 执行此操作,并将标题和第一列作为标识符。
我们将不胜感激。
【问题讨论】:
【参考方案1】:我相信你可以这样做:
awk 's=$0; gsub(FS $2,FS) (NF > 1) print s' file
哪些输出:
CHROM 108 139 159 265 350 351
SNP3 0 0 0 -1 -1 -1
这是如何工作的?
s=$0; gsub(FS $2,FS)
:这个动作包含两部分:
s
中
用字段分隔符FS
替换当前行$0
第二个字段的所有值,包括其起始字段分隔符FS
(FS $2
)。这会产生副作用,重新定义 $0
,并重新定义所有字段变量和字段总数 NF
。如果$2=x
,则需要字段分隔符FS
以避免匹配xx
(NF > 1) print s
:如果您还剩 1 个以上的字段,请打印该行,这意味着您有不同的数字。
【讨论】:
如果我们有一行SNP1 -1 -11 -1 -1 -1 -1
,这将失败,它也会打印这一行。
@RavinderSingh13 应该如此。 -11 与 -1 不同
我的意思是这也会在输出中打印这一行,即使它不应该被打印。
@kvantour 找到最大长度的数字作为模式。但它会比我们在每个列中比较值要慢。
@RavinderSingh13 是的,我已经检查了所有解决方案,它们都运行良好。我非常感谢所有海报的努力:-)【参考方案2】:
你可以试试这个:
awk 'NR==1;NR>1for(i=2;i<NF;i++)if($(i+1)!=$i) print;next' file
它打印标题行。 它循环遍历字段,直到找到与下一个的差异,然后打印它,然后转到下一个。
【讨论】:
【参考方案3】:请您尝试关注一下。
awk 'val=$2;count=1;for(i=3;i<=NF;i++)if(val==$i)count++;if(count!=(NF-1))print' Input_file
【讨论】:
为什么不直接设置val = $2
,然后从3开始循环for i?也不需要计数 - 一旦你找到不等于 val
的列,打印该行并跳出循环。
@Barmar,先生,现在肯定做到了,谢谢你让我知道。【参考方案4】:
便携式 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
【讨论】:
以上是关于如果所有列中的值相同,则删除行的主要内容,如果未能解决你的问题,请参考以下文章