我正在收集大量日志文件的数据,我需要计算唯一字符串的出现次数。通常,这样做的方式是使用如下命令:
zcat <file> | grep -o <filter> | sort | uniq -c | sort -n
我要做的是不要在grep之后支付那种性能惩罚。这可能不用离开bash吗?
答案 0 :(得分:3)
您可以使用awk计算唯一身份,并避免使用sort
:
zgrep -o <filter> <file> |
awk '{count[$0]++} END{for (i in count) print count[i], i}'
另请注意,您可以避免zcat
并直接致电zgrep
。
答案 1 :(得分:1)
既然你提到你不想离开bash:你可以尝试使用关联数组:你可以使用输入行作为键,将计数作为值。要了解关联数组,请参阅此处:http://www.gnu.org/software/bash/manual/html_node/Arrays.html。
但是,一定要对性能进行基准测试 - 尽管如此,使用sort和uniq,或者perl或者......可能会更好。
答案 2 :(得分:1)
jq有内置的关联数组,所以你可以考虑以下方法之一,它们都是有效的(比如awk):
zgrep -o <filter> <file> |
jq -nR 'reduce inputs as $line ({}; .[$line] += 1)'
这将产生作为JSON对象的结果,其频率为对象的值,例如
{
"a": 2,
"b": 1,
"c": 1
}
如果您希望每行输出都包含计数和值(按此顺序),那么适当的jq调用将是:
jq -nRr 'reduce inputs as $line ({}; .[$line] += 1)
| to_entries[] | "\(.value) \(.key)"'
这会产生如下输出:
2 a
1 b
1 c
此处使用的jq
选项为:
-n # for use with `inputs`
-R # "raw" input
-r # "raw" output