我有一个大文件(50 GB),我想计算其中不同行的出现次数。通常我会使用
sort bigfile | uniq -c
但是文件足够大,排序需要大量的时间和内存。我可以
grep -cfx 'one possible line'
对于文件中的每个唯一行,但这意味着 n 为每个可能的行传递文件,这(尽管对内存更友好)比原始行花费的时间更长。
有任何想法吗?
一个相关问题询问了一种在大文件中查找唯一行的方法,但我正在寻找一种方法来计算每个实例的数量——我已经知道可能的行是什么。
我有一个大文件(50 GB),我想计算其中不同行的出现次数。通常我会使用
sort bigfile | uniq -c
但是文件足够大,排序需要大量的时间和内存。我可以
grep -cfx 'one possible line'
对于文件中的每个唯一行,但这意味着 n 为每个可能的行传递文件,这(尽管对内存更友好)比原始行花费的时间更长。
有任何想法吗?
一个相关问题询问了一种在大文件中查找唯一行的方法,但我正在寻找一种方法来计算每个实例的数量——我已经知道可能的行是什么。
利用awk
awk '{c[$0]++} END {for (line in c) print c[line], line}' bigfile.txt
这在时间上是 O(n),在空间上是 O(unique lines)。
这是使用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
}
#!/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