从文本文件中删除包含特定文本的行

时间:2016-06-07 17:26:34

标签: linux perl

我正在尝试删除包含0/0或./的行。在第71栏“FORMAT.1.GT”中,以制表符分隔的文本文件 我尝试了以下代码,但它不起作用。完成此任务的正确方法是什么?谢谢

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

5 个答案:

答案 0 :(得分:1)

由于您需要准确的位置并知道字符串长度substr可以找到它

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

仅当从第71列开始的三字符长字符串与0/0./.

不匹配时,才会打印行

正则表达式周围的{}分隔符允许我们在内部使用/|而无需转义。 ?:就在那里,()仅用于分组,而不是捕获。没有?:也可以正常工作,这只是出于效率的考虑。

答案 1 :(得分:1)

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

答案 2 :(得分: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脚本调用它。

答案 3 :(得分:0)

试试吧!

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

答案 4 :(得分:0)

您的命令的问题在于您正在尝试捕获不产生输出的命令的输出 - 所有匹配都被重定向到文件,因此这就是所有输出的位置。

无论如何,从Perl调用grep只是古怪的。在Perl中读取文件是可行的方法。

如果您确实需要单个shell命令,

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

会更准确,更优雅地完成您的要求。但是您也可以在Perl程序中直接使用该正则表达式。