2016-06-07 185 views
-1

我试图删除包含0/0或./的行。在标签分隔的文本文件的第71列“FORMAT.1.GT”中。
我试过下面的代码,但它不起作用。完成这个的正确方法是什么?谢谢从文本文件中删除包含特定文本的行

my $cmd6 = `fgrep -v "0/0" | fgrep -v "./." $Variantlinestsvfile > $MDLtsvfile`; print "$cmd6"; 
+0

是否要删除整行? –

+0

是的,我想删除整条线。感谢 – user3781528

+0

cat old_file.txt | sed'/\.\/\./d'| sed'/ 0 \/0/d'> new_file.txt –

回答

1

你可以称之为borodin的一行,zdim说。哪一个适合你是不明确的,因为你不知道第71列是指该行的第71个制表符分隔字段还是该行的第71个字符。考虑

12345\t6789 

现在什么是第二列?它是字符2还是字段6789?鲍罗廷的回答假定它是6789,而zdim假设它是2。两种解决方案都可以解决这两种情况,但这些解决方案都是独立解决方案它自己的程序可以从命令行运行。

如果要整合到你的Perl脚本,你可以做这样的:

替换此行:

my $cmd6 = `fgrep -v "0/0" | fgrep -v "./." $Variantlinestsvfile > $MDLtsvfile`; print "$cmd6"; 

在这个片段:

open(my $fh_in, '<', $Variantlinestsvfile) or die "cannot open $Variantlinestsvfile: $!\n"; 
open(my $fh_out, '>', $MDLtsvfile) or die "cannot open $MDLtsvfile: $!\n"; 
while(my $line = <$fh_in>) { 

    # character-based: 
    print $fh_out $line unless (substr($line, 70, 3) =~ m{(?:0/0|\./\.)}); 

    # tab/field-based: 
    my @fields = split(/\s+/, $line); 
    print $fh_out $line unless ($fields[70] =~ m|([0.])/\1|); 
} 
close($fh_in); 
close($fh_out); 

使用基于字符的行基于标签/字段的行。不是都!

Borodin和zdim将这段代码浓缩为一行代码,但不能从Perl脚本中调用该代码。

+0

我很惭愧,因为我只做了两个很好的答案混搭。 – PerlDuck

+0

但这对我来说确实很有意义。谢谢:) – user3781528

+1

@PerlDog这是一篇非常好的文章,在我看来这是一个非常好的答案 - 你将所需的内容放在一起,并以合适的方式回答问题。我说的都很好:)我觉得有趣的是,我们从来没有被告知过它是哪种方式。所以,即使在所有事情都说完了,过去和过去之后,我们仍然无法确定。 – zdim

1

由于您所需要的确切位置,并知道串lenghts substr可以找到它

perl -ne 'print if not substr($_, 70, 3) =~ m{(?:0/0|\./\.)}' filename 

这将打印线仅在三个字符长的字符串开始在第71栏不匹配的任0/0./.

周围的正则表达式的分隔符{}允许我们使用/|内没有逃脱。 ?:在那里,所以()仅用于分组,而不是捕获。如果没有?:,它也可以正常工作,这只是为了提高效率。

+0

True,if _column 71_表示:行中第71个字符 – PerlDuck

+0

@zdim 。如果不是substr($ _,70,3)=〜m {(?:0/0 | \ ./ \。)}'$ currenttsvfile> $ MDLtsvfile',我的$ cmd6 ='perl -ne'; print' $ cmd6“;当我从Perl脚本运行它时给了我错误 – user3781528

+0

@ user3781528对不起,我没有回复你的消息 - 我只是直到现在才看到它(我认为这是因为有一段时间用户名后?)你确实得到了一个解释和你的好回答,所以一切都很好:) – zdim

0

试试吧!

awk '{ if ($71 != "./." && $71 != ".0.") print ; }' old_file.txt > new_file.txt 
+0

有人在这里谁会责怪你_ [无用我们e的猫](http://stackoverflow.com/q/11710552/5830574)_。我没有,但要做好准备。 – PerlDuck

+0

@PerlDog算入我的收藏。 – tripleee

+0

更好? –

1
perl -ane 'print unless $F[70] =~ m|([0.])/\1|' myfile > newfile 
+0

确实如果_column 71_表示:71st制表符分隔的字段。 – PerlDuck

+0

@PerlDog:我们被告知它是一个制表符分隔的文件,列号很少意味着字符位置。此外,如果涉及标签,字符位置非常模糊,特别是当我们不知道标签页的尺寸时 – Borodin

+0

鉴于此,您的答案是正确的。但是zdim的回答也是高调的,所以有人一定认为这是第71个角色。 – PerlDuck

0

在命令中的问题是,你正试图捕捉其不产生输出命令的输出 - 所有的比赛都被重定向到一个文件中,因此,这就是所有的输出是怎么回事。

无论如何,从Perl调用grep只是古怪。在Perl中读取文件本身就是一种方法。

如果你想要一个shell命令,

grep -Ev $'^([^\t]*\t){70}(\./\.|0/0)\t' file 

会做你所要求的更精确和优雅。但是,您也可以在Perl程序中直接使用该正则表达式。