【问题标题】:awk catch text going into the next lineawk 捕获进入下一行的文本
【发布时间】:2010-11-02 15:17:51
【问题描述】:

我有以下问题,也许你可以帮忙:

我要匹配的文字是这样的:

Data Generated using Turbine's method
Stuff
more Stuff
Full speed : 0.87
Data generated using My method
Stuff
more stuff
Full speed : 0.96

Data Generated using Turbine's method
Stuff
more Stuff
Full speed : 0.83
Data generated using My method
Stuff
more stuff
Full speed : 0.94

我想匹配包含全速的行并将它们输出到这样的表格中:

Turbine's My
0.87    0.96
0.83    0.94

所以我可以比较这两种方法。但是我很难让 awk 匹配我当前的正则表达式:

/Data Generated using Turbine's method.*Full speed/
/Data Generated using My method.*Full speed/

我的问题到底是什么?为什么 awk 不匹配这个?

谢谢你的建议

【问题讨论】:

  • 您会知道,在您尝试的正则表达式中,“d*”表示“零或多个 d”。你会想要.*,它的意思是“零个或多个任意字符”(但这并不能解决多行问题)。

标签: shell awk


【解决方案1】:

AWK 中的单个 RE 仅尝试匹配单个行。您似乎想要一个范围模式,例如:/^Data Generated/, /^Full Speed.*$/

编辑:准确地获得您要求的格式相对困难。如果你不介意把它横过来,可以这么说,所以每组都在一行而不是一列,它变得相当简单:

/^Data/     { name = $4; }
/^Full/     { speeds[name] = speeds[name] " " $4; } 

END { 
    for (i in speeds)
        printf("%10s : %s\n", i, speeds[i]);
}

【讨论】:

  • 感谢您捕获了这条线。甚至不知道这些存在。如果你能告诉我如何匹配全速后面的数字,那就完美了
  • “全速后”是什么意思? $4 是匹配时的数字 /^Full/
  • @JimR:他在上面的评论早于编辑,所以他只评论了一个范围的使用(如果我开始更仔细地阅读他的问题,我可能不会建议)。
【解决方案2】:

试试这个:

awk -F: 'BEGIN {OFS="\t"; print "Turbine\047s" OFS "My"} /Turbine/ {tflag=1; mflag=0} /My/ {mflag=1; tflag=0} /Full speed/ {if (tflag) {T=$2; tflag=0}; if (mflag) { print T OFS OFS $2; mflag=0}}' inputfile

在不同的行上:

awk -F: 'BEGIN {OFS="\t"; print "Turbine\047s" OFS "My"}
        /Turbine/ {tflag=1; mflag=0}
        /My/ {mflag=1; tflag=0}
        /Full speed/ {
            if (tflag) {T=$2; tflag=0}; 
            if (mflag) { print T OFS OFS $2; mflag=0}}' inputfile

或者稍微简单一点的版本:

awk -F: '/Turbine/, /^Full speed/ {if ($0 ~ /Full/) T=$2}
         /My/, /^Full speed/ {if ($0 ~ /Full/) print T, $2}'

【讨论】:

【解决方案3】:

我会使用 Perl:

perl -ne '
    if (/(\S+) method/) {$method = $1}
    if (/Full speed : ([\d.]+)/) {push @{$speeds{$method}}, $1}
    END {
        @keys = keys %speeds;
        print join("\t", @keys), "\n";
        $max = 0;
        for $v (values %speeds) {
            $len = scalar @$v; 
            $max = $len if $len > $max;
        }
        for $i (0 .. $max-1) {
            for $k (@keys) {print $speeds{$k}[$i], "\t"}; 
            print "\n";
        }
    }
' speed.txt

哪个输出

My      Turbine's
0.96    0.87
0.94    0.83

【讨论】:

  • 不,感谢它是一个更大的 awk 脚本的所有部分,但无论如何都要感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多