我对文字处理有疑问,但没有强有力的想法。
这是一个包含所有程序执行信息的日志文件,如:
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)
感谢。
答案 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"
}'