bash:从gcov报告

时间:2017-07-19 15:13:10

标签: regex bash sed gcov

gcov是一个GNU工具链实用程序,它生成代码覆盖率报告(请参阅documentation),格式如下:

    -:    0:Source:../../../edg/attribute.c
    -:    0:Graph:tmp.gcno
    -:    0:Data:tmp.gcda
    -:    0:Runs:1
    -:    0:Programs:1
    -:    1:#include <stdio.h>
    -:    2:
    -:    3:int main (void)
    1:    4:{
    1:    5:  int i, total;
    -:    6:
    1:    7:  total = 0;
    -:    8:
   11:    9:  for (i = 0; i < 10; i++)
   10:   10:    total += i;
    -:   11:
    1:   12:  if (total != 45)
#####:   13:    printf ("Failure\n");
    -:   14:  else
    1:   15:    printf ("Success\n");
    1:   16:  return 0;
    -:   17:}

我需要提取从bash脚本执行的行的行号。 $ egrep --regexp='^\s+[1-9]' example_file.c.gcov似乎返回了相关的行。典型输出的例子是:

    1:  978:  attr_name_map = alloc_hash_table(NO_MEMORY_REGION_NUMBER,
   79:  982:  for (k = 0; k<KNOWN_ATTR_TABLE_LENGTH; ++k) {
   78:  989:    attr_name_map_entries[k].descr = &known_attr_table[k];
   78:  990:    *ep = &attr_name_map_entries[k];
    1:  992:}  /* init_attr_name_map */
  519: 2085:      new_attr_seen = FALSE;
  519: 2103:      p_attributes = last_attribute_link(p_attributes);
  519: 2104:    } while (new_attr_seen);
  519: 2106:  return attributes;
   16: 3026:void transform_type_with_gnu_attributes(a_type_ptr        *p_type,
   16: 3041:  for (ap = attributes; ap != NULL; ap = ap->next) {
    1: 6979:void process_alias_fixup_list(void)
    1: 6984:  an_alias_fixup_ptr  entries = alias_fixup_list, entry;

我随后必须提取行号字符串。此示例的预期输出为:

978
982
989
990
992
2085
2103
2104
2106
3026
3041
6979
6984

有人可以建议一种可靠,稳健的方法来实现这一目标吗?

注意: 我的想法是消除未放置在角色:的第一个和第二个实例之间的所有内容,我试图用sed做到目前为止没有取得多大成功。

1 个答案:

答案 0 :(得分:0)

使用awk

这很简单
awk -F: '/ +[0-9]/ {gsub(/ /, "", $2); print $2}' file.gcov

即,使用:作为字段分隔符, 对于以空格和数字开头的行, 替换第二个字段中的空格并打印第二个字段。

但如果你真的想使用sed, 你想要一些健壮的东西,你可以这样做:

sed -e '/^  *[0-9][0-9]*:  *[0-9][0-9]*:/!d' -e 's/[^:]*: *//' -e 's/:.*//' file.gcov

这里发生了什么?

  • 第一个命令使用模式匹配以1个或多个空格开头的行,后跟1个或多个数字后跟:后跟1个或多个空格后跟1个或多个数字后跟1 :。然后是有趣的部分,我们使用!反转此选择,并使用d将其删除。我们有效地删除除了我们需要的所有其他行。

  • 第二个命令是一个简单的替换,替换不是:后跟:后跟零或更多空格的字符序列。该模式从行的开头应用,因此不需要启动^,也不需要严格指定1或更多空格,这要归功于之前的命令我们已经知道至少会有之一。

  • 最后一个命令更简单,替换:及其后的所有内容。

sed的某些版本会为您提供更紧凑的写作风格的快捷方式,例如[0-9]+而不是[0-9][0-9]*,但上面的示例将适用于更广泛的实现(特别是BSD)。