如何计算对数并找到未配对的?

时间:2015-04-07 03:02:27

标签: algorithm bash shell pattern-matching

我对文字处理有疑问,但没有强有力的想法。

这是一个包含所有程序执行信息的日志文件,如:

12:34:21 End   ./calc
12:34:25 Start ./gemm
12:34:26 Start ./gemm
12:34:27 Start ./jacobi
12:34:46 End   ./gemm
12:34:51 Start ./fab
12:35:02 End   ./jacobi

所以在这种情况下,我试图找到这对"开始"和"结束"特定计划。例如, jacobi 因为它有开始和结束而被配对。 fab 没有配对,因为我们无法找到其结束信息。 gemm 有两个Start和一个End。因此,Start中的一个配对。我可以设置一个规则,比如First Execution First Finish,然后第二行 gemm 没有配对。 calc 未配对,因为它没有开始信息。

使用bash,我可以grep开始或结束,然后对结果进行排序并进行比较。真的不认为它是一个强大的解决方案。有什么想法吗?

提供bash代码很好,也欢迎算法!

预期产出:

12:34:21 End   ./calc     (unpaired)
12:34:25 Start ./gemm     (paired)
12:34:26 Start ./gemm     (unpaired)
12:34:27 Start ./jacobi   (paired)
12:34:46 End   ./gemm     (paired)
12:34:51 Start ./fab      (unpaired)
12:35:02 End   ./jacobi   (paired)

感谢。

1 个答案:

答案 0 :(得分:2)

你可以使用关联数组在bash v4中执行此操作,其方式与下面的小awk程序完全相同,但是awk程序更容易,并且不依赖于你有一个新的bash版本。< / p>

它基本上为第三个字段的每个值设置一个队列。 Start条目的行号被添加到队列的末尾。遇到End时,如果可能,Start条目将从队列前面移开,并且两个条目都标记为匹配。

awk '
  { line[NR] = $0; s = start[$3] }
  $2=="End" && s {
      matched[s] = 1; matched[NR] = 1; start[$3] = link[s]
  }
  $2=="Start" {
      if (s) link[end[$3]] = NR; else start[$3] = NR;             
      end[$3] = NR;
  }    
  END {
      for (i = 1; i <= NR; ++i)
          printf "%s (%spaired)\n", line[i], matched[i] ? "" : "un"
  }'