我正在尝试删除包含0/0或./的行。在第71栏“FORMAT.1.GT”中,以制表符分隔的文本文件 我尝试了以下代码,但它不起作用。完成此任务的正确方法是什么?谢谢
my $cmd6 = `fgrep -v "0/0" | fgrep -v "./." $Variantlinestsvfile > $MDLtsvfile`; print "$cmd6";
答案 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程序中直接使用该正则表达式。