寻找大文件的 uniq -c 替代品

Finding a uniq -c substitute for big files

我有一个大文件 (50 GB),我想计算其中不同行的出现次数。通常我会使用

sort bigfile | uniq -c

但是文件太大,排序需要大量的时间和内存。我可以

grep -cfx 'one possible line'

对于文件中的每一行,但这意味着 n 遍历每一行可能的文件,这(尽管对内存更友好)比原始行花费的时间甚至更长。

有什么想法吗?


A related question 询问如何在大文件中 找到 独特的行,但我正在寻找一种方法来 count 每个实例的数量——我已经知道可能的行是什么了。

#!/bin/bash
# port this logic to awk or ksh93 to make it fast

declare -A counts=( )
while IFS= read -r line; do
  counts[$line]=$(( counts[$line] + 1 )) # increment counter
done

# print results
for key in "${!counts[@]}"; do
  count=${counts[$key]}
  echo "Found $count instances of $key"
done

使用awk

awk '{c[[=10=]]++} END {for (line in c) print c[line], line}' bigfile.txt

时间复杂度为 O(n),时间复杂度为 O(unique lines) space。

这是一个使用 jq 1.5 的解决方案。它在方法和性能特征方面与 awk 解决方案基本相同,但输出是一个表示散列的 JSON 对象。 (可以简单地修改该程序以生成另一种格式的输出。)

调用:

$ jq -nR 'reduce inputs as $line ({}; .[$line] += 1)' bigfile.txt

如果 bigfile.txt 由这些行组成:

a
a
b
a
c

那么输出将是:

{
  "a": 3,
  "b": 1,
  "c": 1
}