【问题标题】:Remove lines in a file that do not have specified patterns in particular columns删除文件中在特定列中没有指定模式的行
【发布时间】:2011-10-09 07:39:27
【问题描述】:

我有一个制表符分隔的文本文件。我已将其拆分为列。前 2 列中的每一列都包含一个 ID 号。

我想保留 ID 号以 P 或 Q 开头的所有行,并删除第 1 或第 2 列具有任何其他 ID 或为空白的任何其他行。

例如。所以要保留的列将是这样的:P12345 或 Q12345。要删除的列将是 GAG123、CH123 等,或者只是空白。

我不知道该怎么做。我尝试将行拆分为数组和 grep /^[PQ]/elements [0] 和 [1] 以及其他各种东西,但我一定是做错了什么。

我从 TLP 尝试了以下代码,但它不起作用,我知道我一定是做错了什么:

#!/usr/bin/perl  

use warnings;
use strict;

open(FILE,"<myfile.txt"); 
my @LINES = <FILE>; 
open(my $outfile, '>', 'changedtxt');
my @wanted;

while (<FILE>) {
    my @fields = split('\t', $_);
    if ( $fields[0] =~ /^[PQ]/ and $fields[1] =~ /^[PQ]/ ) {
        push @wanted, $_;  
        print {$outfile} $_;    
    }
}
exit:

【问题讨论】:

  • 请发布您目前拥有的代码。
  • 到目前为止你得到了什么代码?
  • 如果一个 ID 以 P 或 Q 开头,而另一个 ID 不以 P 或 Q 开头怎么办?
  • 由于您将文件 slurp 到 @LINES,因此 while 循环不会运行。如果您删除该行,它应该可以工作。虽然您不需要显式打开文件,但只需使用 shell 重定向,例如script.pl input.txt &gt; output.txt.
  • 效果很好,非常感谢!

标签: perl file replace grep


【解决方案1】:

您可以使用awk打印出第一个或第二个字段以P或Q开头的记录:

awk -F'\t' '$1~/[PQ].*/ || $2~/[PQ].*/ {print}'  file

【讨论】:

    【解决方案2】:
    use strict;
    use warnings;
    
    my @wanted;
    while (<$fh>) {
        my @fields = split /\t/, $_;
        if ( $fields[0] =~ /^[PQ]/ or $fields[1] =~ /^[PQ]/ ) {
            push @wanted, $_;
        }
    }
    

    如果您希望两个 ID 都以 P 或 Q 开头,请将 or 交换为 and

    如果您只是想将想要的行移动到另一个文件,只需执行以下操作:

    perl -wnae 'print if (($F[0] =~ /^[PQ]/) or ($F[1] =~ /^[PQ]/))' input.txt > output.txt
    

    或作为脚本,与script.pl input.txt &gt; output.txt一起使用:

    use warnings;
    use strict;
    
    while (<>) {
        my @fields = split(/\t/, $_);
        print if ( $fields[0] =~ /^[PQ]/ and $fields[1] =~ /^[PQ]/ );
    
    } 
    

    请注意,您不能将'\t' 用作拆分模式。

    【讨论】:

    • 使用此代码,您不会得到任何输出。您只需在 @wanted 数组中获得所需的行。如果你想要输出,你必须添加它。
    • 对不起,我本来想添加我的附加代码,但它在我有机会做之前添加了我的评论!
    • 现在附加到我上面的问题
    • 您还应该定义文件句柄。
    • 哦,顺便问一下,您的字段是否包含空格?在选项卡上显式拆分可能是谨慎的。
    【解决方案3】:

    你也可以一行完成:

    cat yourfile.txt | perl -e 'while (<>) { print if m/^[PQ]/xmsi && m/\t+[PQ]/xmsi }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多