Shell Awk&;sed文本操作(从特定组中提取最大负值)

Shell Awk&;sed文本操作(从特定组中提取最大负值),shell,sed,awk,Shell,Sed,Awk,我确实有文本操作问题,需要在awk、sed和shell中解决。 我的文本如下所示: >Sample_1 100 101 aaattattacaaaaataattacaaattattacaaaaagaattattacaaaaagaattacaaaa -1.60 .(((((((.....)))))))............................

我确实有文本操作问题,需要在awk、sed和shell中解决。
我的文本如下所示:

>Sample_1
    100                                                            101
    aaattattacaaaaataattacaaattattacaaaaagaattattacaaaaagaattacaaaa
-1.60   .(((((((.....)))))))...........................................  []
>Sample_2
    1                                35
    aattattacaaaaagaattattacaaaaagaatta
0.00    ...................................  _
>Sample_3
    1                                     123
    gctcacacctgtaatcccagcactttgggaggctgagg
-27.80  ((((.....))))......((((((.(((...))))))).)[][][[][]]
-26.40  (((((.((...(((((..((((((....)).........  [[][]][]
-25.80  ((((.....)))).....((((((...............  [][][][[][]]
    123                                  145
    ctgaggcaggcagatcacgaggtcacgagatcaa
-26.20  (((.....))))))  [][][[][]]
-25.90  ....((((..((....))  [][[][]]
-25.70  ..(((..((....))..(())  [[][]][[][]]
    145                                 256
    gtaatcccagcactttgggaggctgaggcaggcaga
0.00    ...........................................  _
    256                                 342
-25.00  ..((....((((.....((((((...)))....))...  [[][]]
-24.00  ..((.((((.((((())...  [[][][]]
-23.70  .((((((...(((((..((..  [[][]][]
我想:

  • 提取样本名称(
    >Sample_1
  • 提取样本名称后面的数值(0或负值)
  • 从负值组(例如,
    -27.80;-26.40;-25.80
    )中提取最先出现的数字(它是最负的值)
  • 完美输出如下所示:

    >Sample_1  
    -1.60  
    >Sample_2  
    0.00  
    >Sample_3  
    -27.80  
    -26.20  
    0.00  
    -25.00
    
    我尝试在awk打印$1、灰色“>”、0和负值时这样做,但无法将列分成多个组并提取最负的值

    awk '{print $1}' file | egrep -i '>|0.00|-'
    

    您使用
    sed
    awk
    标记了您的问题,但是如果您使用Perl,您可以编写:

    #!/usr/bin/perl -w
    
    use warnings;
    use strict;
    
    my $min = undef;
    
    while(<>)
    {
      if(m/^(-?\d+\.\d+)/)
      {
        if(! defined($min) || $1 < $min)
          { $min = $1; }
      }
      else
      {
        if(defined $min)
        {
          print "$min\n";
          $min = undef;
        }
        if(m/^>/)
          { print; }
      }
    }
    
    if(defined $min)
      { print "$min\n"; }
    
    #/usr/bin/perl-w
    使用警告;
    严格使用;
    我的$min=undf;
    while()
    {
    如果(m/^(-?\d+\.\d+/)
    {
    如果(!已定义($min)| |$1<$min)
    {$min=$1;}
    }
    其他的
    {
    如果(定义为$min)
    {
    打印“$min\n”;
    $min=未定义;
    }
    如果(m/^>/)
    {print;}
    }
    }
    如果(定义为$min)
    {打印“$min\n”;}
    
    您将问题标记为
    sed
    awk
    ,但如果您对Perl没有问题,您可以编写:

    #!/usr/bin/perl -w
    
    use warnings;
    use strict;
    
    my $min = undef;
    
    while(<>)
    {
      if(m/^(-?\d+\.\d+)/)
      {
        if(! defined($min) || $1 < $min)
          { $min = $1; }
      }
      else
      {
        if(defined $min)
        {
          print "$min\n";
          $min = undef;
        }
        if(m/^>/)
          { print; }
      }
    }
    
    if(defined $min)
      { print "$min\n"; }
    
    #/usr/bin/perl-w
    使用警告;
    严格使用;
    我的$min=undf;
    while()
    {
    如果(m/^(-?\d+\.\d+/)
    {
    如果(!已定义($min)| |$1<$min)
    {$min=$1;}
    }
    其他的
    {
    如果(定义为$min)
    {
    打印“$min\n”;
    $min=未定义;
    }
    如果(m/^>/)
    {print;}
    }
    }
    如果(定义为$min)
    {打印“$min\n”;}
    
    工作起来很有魅力。但我还想问,是否有可能使用perl one liner:在输出上运行它,这样我就可以为数值(例如-40)设置阈值,并获得值低于-40的示例名称?@Poe:为此,您可以编写
    。|perl-ne'print if m/^>/或$<-40'| grep-b1^-
    。工作起来很有魅力。但我还想问,是否有可能使用perl one liner:在输出上运行它,这样我就可以为数值(例如-40)设置阈值,并获得值低于-40的示例名称?@Poe:为此,您可以编写
    。|perl-ne'如果m/^>/或$<-40'| grep-b1^-
    打印。