【问题标题】:how can I count number of lines after a string match until next especific match occurs如何计算字符串匹配后的行数,直到发生下一个特定匹配
【发布时间】:2020-03-29 11:15:51
【问题描述】:

我有一个具有以下结构的文件(见下文),我需要帮助来找到匹配每个“>集群”字符串的方法,并且对于每种情况,计算直到下一个“集群”之前的行数等等直到文件结束。

>Cluster 0
0       10565nt, >CL9602.Contig1_All... *
1       1331nt, >CL9602.Contig2_All... at -/98.05%
>Cluster 1
0       3798nt, >CL3196.Contig1_All... at +/97.63%
1       9084nt, >CL3196.Contig3_All... *
>Cluster 2
0       8710nt, >Unigene21841_All... *
>Cluster 3
0       8457nt, >Unigene10299_All... *

所需的输出应如下所示:

Cluster 0  2 
Cluster 1  2
Cluster 2  1
Cluster 3  1

我尝试使用 awk 如下,但它只给了我行号。

awk '{print FNR "\t" $0}' All-Unigene_Clustered.fa.clstr | head - 20
==> standard input <==
1       >Cluster 0
2       0       10565nt, >CL9602.Contig1_All... *
3       1       1331nt, >CL9602.Contig2_All... at -/98.05%
4       >Cluster 1
5       0       3798nt, >CL3196.Contig1_All... at +/97.63%
6       1       9084nt, >CL3196.Contig3_All... *
7       >Cluster 2
8       0       8710nt, >Unigene21841_All... *
9       >Cluster 3
10      0       8457nt, >Unigene10299_All... *

我也尝试过使用 sed,但它只打印行,甚至省略了一些行。

sed -n -e '/>Cluster/,/>Cluster/ p' All-Unigene_Clustered.fa.clstr | head             
>Cluster 0
0       10565nt, >CL9602.Contig1_All... *
1       1331nt, >CL9602.Contig2_All... at -/98.05%
>Cluster 1
>Cluster 2
0       8710nt, >Unigene21841_All... *
>Cluster 3
>Cluster 4
0       1518nt, >CL2313.Contig1_All... at -/95.13%
1       8323nt, >CL2313.Contig8_All... *

此外,我尝试将 awk 和 sed 与 'wc' 结合使用,但它只为我提供了字符串匹配的总发生次数。

我想用 grep 的 -v 选项减去不匹配字符串 '>cluster' 的行,然后减去匹配字符串 '>Cluster' 的每一行,然后将两者都添加到一个新文件中,例如

grep -vw '>Cluster' All-Unigene_Clustered.fa.clstr | head
0       10565nt, >CL9602.Contig1_All... *
1       1331nt, >CL9602.Contig2_All... at -/98.05%
0       3798nt, >CL3196.Contig1_All... at +/97.63%
1       9084nt, >CL3196.Contig3_All... *
0       8710nt, >Unigene21841_All... *
0       8457nt, >Unigene10299_All... *
0       1518nt, >CL2313.Contig1_All... at -/95.13%

grep -w '>Cluster' All-Unigene_Clustered.fa.clstr | head
>Cluster 0
>Cluster 1
>Cluster 2
>Cluster 3
>Cluster 4

但问题是每个 '>Cluster' 后面的行数不是恒定的,每个 '>Cluster' 字符串后面跟着 1、2、3 或更多行,直到下一个字符串出现。

在之前回答的问题中广泛搜索帮助后,我决定发布我的问题,但我找不到任何有用的答案。

谢谢

【问题讨论】:

  • 因此,我们确实鼓励人们为解决自己的问题付出努力,所以请在您的问题中添加相同的内容,然后让我们知道。(我不知道顺便说一句)

标签: string perl awk sed grep


【解决方案1】:

perl中的代码可以是下面的形式

use strict;
use warnings;

my $cluster;
my $count;

while( <DATA> ) {
    chomp;
    if( /Cluster \d+/ ) {
        print "$cluster $count\n" if defined $cluster;
        s/>//;
        $cluster = $_;
        $count   = 0;
    } else {
        $count++;
    }
}

print "$cluster $count\n" if defined $store;

__DATA__
>Cluster 0
0       10565nt, >CL9602.Contig1_All... *
1       1331nt, >CL9602.Contig2_All... at -/98.05%
>Cluster 1
0       3798nt, >CL3196.Contig1_All... at +/97.63%
1       9084nt, >CL3196.Contig3_All... *
>Cluster 2
0       8710nt, >Unigene21841_All... *
>Cluster 3
0       8457nt, >Unigene10299_All... *

输出

Cluster 0 2
Cluster 1 2
Cluster 2 1
Cluster 3 1

【讨论】:

    【解决方案2】:

    使用 GNU awk 进行多字符 RS:

    $ awk -v RS='(^|\n)(>|$)' -F'\n' 'NR>1{print $1, NF-1}' file
    Cluster 0 2
    Cluster 1 2
    Cluster 2 1
    Cluster 3 1
    

    上面只是将输入分成以&gt;开头的记录,然后打印每条记录的行数(&gt;Cluster...行减去1)。

    【讨论】:

      【解决方案3】:

      这是Perl 中的一个,尽管非常冗长。我真的不擅长打高尔夫球。

      perl -n -e "if ( /^>(.+)/ ) { print qq($last, $count\n) if $count; $last = $1; $count = 0; } else { $count++ } END { print qq($last, $count) }" All-Unigene_Clustered.fa.clstr
      

      这适用于 Windows。对于 unix shell,您可能需要将双引号更改为单引号。

      【讨论】:

      • 感谢您抽出宝贵时间帮助解决我的问题,很遗憾,您建议的代码没有产生所需的输出,见下文
      • 根据您的示例数据,它会产生您想要的输出。好吧,除了逗号,但删除它是微不足道的。
      • 它是这样的 0>Cluster 31021, 1>Cluster 31021, 1>Cluster 31022, 0>Cluster 31022, 1>Cluster 31022, 1>Cluster 31023, 0>Cluster 31023, 1>集群 31023,
      • 对,,&gt;。我删除了它们。请再试一次
      【解决方案4】:

      请您尝试关注一下。

      awk '
      /^>Cluster/{
        if(count){
          print prev,count
        }
        sub(/^>/,"")
        prev=$0
        count=""
        next
      }
      {
        count++
      }
      END{
        if(count && prev){
          print prev,count
        }
      }
      ' Input_file
      

      说明:为上述代码添加说明。

      awk '                      ##Starting awk program from here.
      /^>Cluster/{               ##Checking condition if a line is having string Cluster then do following.
        if(count){               ##Checking condition if variable count is NOT NULL then do following.
          print prev,count       ##Printing prev and count variable here.
        }                        ##Closing BLOCK for if condition here.
        sub(/^>/,"")             ##Using sub for substitution of starting > with NULL in current line.
        prev=$0                  ##Creating a variable named prev whose value is current line.
        count=""                 ##Nullifying count variable here.
        next                     ##next will skip all further statements from here.
      }                          ##Closing BLOCK for Cluster condition here.
      {
        count++                  ##Doing increment of variable count each time cursor comes here.
      }
      END{                       ##Mentioning END BLOCK for this program.
        if(count && prev){       ##Checking condition if variable count and prev are NOT NULL then do following.
          print prev,count       ##Printing prev and count variable here.
        }                        ##Closing BLOCK for if condition here.
      }                          ##Closing BLOCK for END BLOCK of this program.
      ' Input_file               ##Mentioning Input_file name here.
      

      输出如下。

      Cluster 0 2
      Cluster 1 2
      Cluster 2 1
      Cluster 3 1
      

      【讨论】:

      • 非常感谢 RavinderSingh13。该解决方案完美运行。为了让我和其他人能够理解和学习更多,如果没有问题,请您解释一下这段代码是如何工作的。
      • @LeonardoMartin,详细解释已在我的帖子中添加,请仔细阅读,如果有任何疑问,请告诉我?
      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 2018-10-08
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      相关资源
      最近更新 更多