我的目标是从包含以下行的文件中计算统计信息:
2024-05-08 11:02:58,731 INFO o.a.j.a.J.Some check: Closest Day: Wed, New quantity for [email protected] is: 1
我需要计算有多少封电子邮件具有相同的唯一编号。例如:
1 - 6575 emails
2 - 333 emails
等等。
该文件可能包含同一电子邮件的重复行,因此我使用
awk '!seen[$1]++'
将其过滤掉。
我为此目的创建了 bash 脚本。它可以工作,但是对于数百 MB 的文件来说,速度非常慢并且需要很长时间才能计算。有没有办法优化它?我认为逐行浏览并不是最好的方法。
#!/bin/bash
input_file="$1"
closest_date=$(grep "Closest Day:" "$input_file" | rev | cut -d' ' -f1,3 | rev | awk '!seen[$1]++')
declare -A counts
# Iterate over each line of closest_draw_data
while read -r line; do
# Extract email and number
email=$(echo "$line" | cut -d' ' -f1)
number=$(echo "$line" | cut -d' ' -f2)
# Increment count for the number
(( counts[$number]++ ))
done <<< "$closest_date"
# Print the counts
for number in "${!counts[@]}"; do
echo "Number $number: ${counts[$number]}"
done
请更换该部件
# Iterate over each line of closest_draw_data
while read -r line; do
# Extract email and number
email=$(echo "$line" | cut -d' ' -f1)
number=$(echo "$line" | cut -d' ' -f2)
# Increment count for the number
(( counts[$number]++ ))
done <<< "$closest_date"
# Print the counts
for number in "${!counts[@]}"; do
echo "Number $number: ${counts[$number]}"
done
使用
awk 'BEGIN{FS="[ ]"}{counts[$2]+=1}END{for(number in counts){print "Number",number":",counts[number]}}' "$closest_date"
然后检查输出是否可接受。您的要求以及您是否获得任何加速。此解决方案假设您接受输出中的任何行顺序,如果您需要特定顺序,则相应地设置
PROCINFO["sorted_in"]
。
说明:我通知 GNU
AWK
空格是字段分隔符(以使其与您的 cut
用法保持一致),对于每一行,我将键第二个字段值下的数组中的值增加 1。处理行后,我使用循环迭代数组并以类似于 echo
的形式打印有关值中键的信息。请注意,数字和 ,
之间没有 :
,因为您的 echo
中没有空格。
(在 GNU Awk 5.1.0 中测试)
整个脚本似乎可以是一个 awk 调用:
awk '
/Closest Day:/ && !seen[ $(NF-2) ]++ {
counts[ $NF ]++
}
END {
for (i in counts)
printf "Number %d: %d\n", i, counts[i]
}
' "$1"
如果存储电子邮件和计数数组会消耗太多内存,您可以这样做:
awk '/Closest Day:/ { print $(NF-2),$NF }' "$1" |
sort -u -k1,1 |
cut -d' ' -f2 |
sort -n |
uniq -c |
awk '{ printf "Number %d: %d\n", $2, $1 }'
(
sort
只在内存中保留有限数量的数据,其他命令只需要缓冲一行。)