awk 和 sed 文本操作(从特定组中提取大多数负值)

Posted

技术标签:

【中文标题】awk 和 sed 文本操作(从特定组中提取大多数负值)【英文标题】:Awk & sed text manipulation (extract most negative value from specific group) 【发布时间】:2012-09-23 18:35:17 【问题描述】:

我确实有需要在 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、grepping '>'、0 和负值时执行此操作,但无法将列分成组 & 并提取最负值。

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

【问题讨论】:

【参考方案1】:

您使用sedawk 标记了您的问题,但如果您没问题的话。用 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"; 

【讨论】:

像魅力一样工作。但我也想问是否有可能有一个 perl 单行:在输出上运行它,以便我可以为数值设置阈值(例如-40)并获取值低于该值的样本名称-40? @Poe:为此,你可以写... | perl -ne 'print if m/^&gt;/ or $_ &lt; -40' | grep -B 1 ^-【参考方案2】:
awk '/^[0-]/ && new_group print $1 new_group = (/^[ \t]/) /^>/' file

【讨论】:

以上是关于awk 和 sed 文本操作(从特定组中提取大多数负值)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sed、awk 或 gawk 仅打印匹配的内容?

文本三剑客之awk

Linux的awk、grep、sed工具,实现文本查找、编辑 、格式化

Linux环境下文本处理,提取需要的内容?

使用 bash 命令 awk sed 等从脚本中提取参数字段

使用 awk 或 perl 从 CSV 中提取特定列(解析)