使用bash脚本提取某些类型名称和相应的数字

时间:2012-02-21 21:34:19

标签: bash sed awk extract

A: XXX (Done after 2 rounds)
A: YYY (Done after 1 rounds)
A: ZZZZ (Done after 4 rounds)
A: XXX (Done after 2 rounds)
A: ZZZZ (Done after 1 rounds)
A: YYY (Done after 2 rounds)
A: YYY (Done after 1 rounds)

对于上述文件,我想提取某些名称,例如XXX,YYY,ZZZZ以及每个名字的轮数。

最后,我期望的结果是:

XXX 2 2
YYY 1 2 1
ZZZZ 4 1

我觉得我应该使用sed或awk,但不知道如何使用它们。有没有人有好的解决方案?非常感谢。

3 个答案:

答案 0 :(得分:5)

awk '{ names[$2] = names[$2] " " $5; } END { for (name in names) print name " " names[name] }' file

<强>解释

每个输入行都传递给命令names[$2] = names[$2] " " $5,该命令创建一个名为names的数组,其索引不是数字 - 它们是输入行中显示为第二个字段的单词: XXXYYYZZZZ。它们的值在每行的第5个字段中累积相应的数字。

当输入文件用完时,END会遍历索引名称,打印每个名称后跟其累计数字字符串。

答案 1 :(得分:1)

我喜欢这样的Perl数据结构(数组的哈希):

perl -lane '
        push @{$packets{$F[1]}}, $F[4]
    } 
    END {
        foreach $name (keys %packets) {print join(" ", $name, @{$packets{$name}})
    }
'

答案 2 :(得分:0)

这可能对您有用:

cut -d' ' -f2,5 file |
sort -sk1,1 |
sed ':a;$!N;s/^\(\(\S\+\).*\)\n\2/\1/;ta;P;D'
XXX 2 2
YYY 1 2 1
ZZZZ 4 1

说明:

  • 使用XXX 2
  • 提取第一行cut -d' ' -f2,5 file上的字段2和5
  • 按第一个字段排序,但保留订单sort -sk1,1
  • Sed连接第一个字段相同的行,并附加第二个字段。 sed ':a;$!N;s/^\(\(\S\+\).*\)\n\2/\1/;ta;P;D'

Ths sed命令的工作原理如下:

  • 创建标签:a
  • 在当前行(模式空间PS)上添加换行符,然后在下一行附加换行符,除非它是最后一行。 $!N
  • 使用substitution命令将当前行的第一个字段与上一行的第一个字段匹配,然后将其与前一个换行符一起删除。 s/^\(\(\S\+\).*\)\n\2/\1/
  • 如果替换成功分支到标签。 ta
  • 如果替换不成功,请将PS打印到第一个换行符。 P
  • 删除PS并包含第一个换行符,然后在不刷新PS的情况下开始新的循环。 D