我有一个包含几列的文件。我想从此文件中删除第一列和第二列显示相同值的整行。
例如我的文件如下:
Variant rsid chr pos
1:10177_A_AC rs367896724 1 10177
1:10352_T_TA rs201106462 1 10352
1:10511_G_A rs534229142 1 10511
1:10616_CCGCCGTTGCAAAGGCGCGCCG_C 1:10616_CCGCCGTTGCAAAGGCGCGCCG_C 1 10616
我想删除列中的值Variant
等于rsid
列的行,因此我想获得如下所示的最终文件:
Variant rsid chr pos
1:10177_A_AC rs367896724 1 10177
1:10352_T_TA rs201106462 1 10352
1:10511_G_A rs534229142 1 10511
我尝试运行以下命令:
awk '$1==$2{sed -i} input.file > output.file
awk -F, '$1==$2' input.file > output.file
但它们都不起作用。
我如何使用awk
and/or来解决这个问题sed
?
答案1
你几乎成功了
awk '$1!=$2' input.file > output.file
这将保留第一个和第二个字段不同的行(因此在相等时删除)。
-F,
是错误的,因为,
不是你的字段分隔符,这样设置会让 awk 误解行内容'$1==$2{sed -i}
既不是 awk,也不是 sed 函数
答案2
你已经拥有了最好的一般答案,但在您的具体情况下,您也可以简单地选择第二个字段以 开头的所有行rs
:
$ awk '$2 ~ /^rs/' file
Variant rsid chr pos
1:10177_A_AC rs367896724 1 10177
1:10352_T_TA rs201106462 1 10352
1:10511_G_A rs534229142 1 10511
答案3
可能有一天(这一天可能永远不会到来),您需要在文件操作中做一些“聪明”的事情,而 Awk 解决方案会变得极其复杂。您不需要为一次性任务编写脚本,而是需要基于您的 Awk 经验的东西。你想要一个Perl 单行代码。
这是与上述命令等效的命令(-a
标志显示像awk一样做)
perl -anE 'print if $F[0] ne $F[1]' input.file > output.file
或者
perl -anE 'print if $F[1] =~ /^rs/' input.file > output.file
如果您想就地更改该文件,
perl -i.bak -anE 'print if $F[0] ne $F[1]' input.file
将进行更改input.file
并保留备份input.file.bak
如果您想在完成文件后执行一些代码,请尝试“接吻”运算符}{
perl -i.bak -anE 'if ($F[0] ne $F[1]) {print} else {$del++} }{ $del ||= 0; say "Deleted $del lines"' input.file
答案4
#!/usr/bin/python
m=open('filename','r')
import re
h=re.compile(r'\s+')
for b in m:
fg=re.sub(h," ",b)
rt=fg.split(' ')
if (rt[0] != rt[1]):
print fg
输出
Variant rsid chr pos
1:10177_A_AC rs367896724 1 10177
1:10352_T_TA rs201106462 1 10352
1:10511_G_A rs534229142 1 10511