寻找大文件的 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
}
我有一个大文件 (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
}