【问题标题】:how to skip to a specif line and parse after that - perl如何跳到特定行并在那之后解析 - perl
【发布时间】:2017-08-06 16:52:17
【问题描述】:

我有一个文件,前几行有一些文字,然后是一些表格输出。 我想削减第一行,然后跳到表格输出,但是遇到了一些麻烦(尽管听起来很简单)。 我的策略是找到标题

示例输入文件:

Query         [VOG0001]|NC_002014-NP_040572.1| 1296..1562 + 88 aa|G V protein
Match_columns 100
No_of_seqs    7 out of 16
Neff          2.6 

No Hit                             Prob E-value P-value  Score    SS Cols Query HMM  Template HMM
1 d1gvpa_ b.40.4.7 (A:) Gene V p 100.0 1.6E-38 1.4E-43  221.5   0.0   87    2-89      1-87  (87)
2 d1gvpa_ b.40.4.7 (A:) Gene V p 100.0 1.6E-38 1.4E-43  221.5   0.0   87    2-89      1-87  (87)
3 d1gvpa_ b.40.4.7 (A:) Gene V p 100.0 1.6E-38 1.4E-43  221.5   0.0   87    2-89      1-87  (87)

尝试解析脚本:

open (IN, $hhr_report) or die "cannot open $hhr_report\n";
while (my $line=<IN>){
    if ($line =~/^Query/){
            my @query=split(/\|/,$line);
            my $vogL=$query[0];
            my @vogL2=split(/\s+/,$vogL);
            $vog=$vogL2[1];
            $vog=~ s/\[//g;
            $vog=~ s/\]//g;
    print "query_array:\t@query\n";
    print "query_vog:\t$vog\n";
    }
    next until ($line =~/Query HMM/);
    #next if ($line =~/Query HMM/);
    #next until ($line =~/^No\s[0-9]+/);
    print "$line\n";
    my @columns = split(/\s+/,$line);

... }

我不确定我是否遗漏了一些简单的东西。 但现在我似乎只在解析标题行(包含查询 HMM),但我想解析之后的行。

任何帮助表示赞赏。

【问题讨论】:

  • 您的next until 没有意义。此外,您忘记包含 while 循环的结尾。我不清楚你想做什么。你说你想跳到桌子,但在你的代码中,你做的第一件事就是阅读第一行,它甚至离桌子都不远。请edit并添加说明。
  • 对不起,我想解析第一行,然后跳到表格部分(上面已编辑)。我没有包括整个 while 循环,因为这并不重要,因为我只解析第一行,然后是表的标题
  • 使用词法变量,而不是裸词文件句柄。使用 3-arg open,而不是 2-arg open。在错误消息中包含$!

标签: perl


【解决方案1】:

我会尝试丢弃直到标题行的所有内容(或解析第一行), 然后开始解析标题后面的行,如下所示:

#!/usr/bin/env perl
use strict;
use warnings;

open (my $fh, "<", $hhr_report) or die "Cannot open $hhr_report: $!";

my $header;
do {
    $header = <$fh>;
    # If you need to parse lines before the header for some reason,
    # do that here
}while( !is_header($header) );

# If you like, parse the header column to get the column names

my @lines;

while ( my $line = <$fh> ){

    my @columns = split_line($line);
    push @lines, \@columns;

}

sub is_header {
    my $line = shift;

    return $line =~ /^No\sHit/ ? 1 : 0;
}

sub split_line {
    my $line = shift;
    # Here, use a regex to split the columns, depending on what you need. 
    # You could also consider outputting errors if the line is malformatted or missing important values

}

【讨论】:

    【解决方案2】:

    我认为你想要完成的事情可以更简单地完成。我了解您想要:

    1. 获取文件的第一行并处理它
    2. 在表格前跳过下一行
    3. 处理表格数据

    如果是这样,你可以这样做:

    open (IN, $hhr_report) or die "cannot open $hhr_report\n";
    
    # Get the first line of the file and process it:
    my $first_line = <$fh>;
    my @query=split(/\|/,$first_line);
    my $vogL=$query[0];
    my @vogL2=split(/\s+/,$vogL);
    my $vog=$vogL2[1];
    $vog=~ s/\[//g; #/
    $vog=~ s/\]//g; #/
    print "query_array:\t@query\n";
    print "query_vog:\t$vog\n";
    
    # Work on the rest of the file:
    my $in_table = 0; 
    while (my $line=<IN>){
        if ($in_table) {
            # process your columns here
            print "$line\n";
            my @columns = split(/\s+/,$line);
            ... # the rest of your processing
        }
        # read (and throw away) lines until you match the table header:
        $in_table = 1 if $line =~/Query HMM/;
        # next time through the while loop you'll have your 
        # first tabular data and the $in_table will be true
    }
    

    【讨论】:

      猜你喜欢
      • 2015-04-06
      • 1970-01-01
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-02
      • 1970-01-01
      • 2021-07-24
      相关资源
      最近更新 更多