如何对 uniq -c 返回的值进行算术运算?
How to do arithmetic operations on value returned by uniq -c?
我有 Apache 网络服务器的访问日志文件。使用 Linux/UNIX shell 命令我计算了文件中唯一日期的数量。命令 uniq -c
返回文件中每个唯一日期的出现次数。是否可以对 uniq -c
返回的值进行算术运算,或者是否有任何其他方法来计算出现次数并进行算术运算?这是我的 Linux commads:
grep -E [0-9][0-9]/[A-Z]{1}[a-z]{2}/[0-9]{4} log.txt | sed 's/.*\(..\)\/Oct\/\(....\).*/-10-/' | sort | uniq -c | sort -ru | head -10
这里是输出:
358 2006-10-09
348 2006-10-10
347 2006-10-01
344 2006-10-20
339 2006-10-25
337 2006-10-24
337 2006-10-12
336 2006-10-06
336 2006-10-02
335 2006-10-19
您可能对单个 awk script that does all the above in a single go (with exception of the sorting). Also, awk 感兴趣,如果您想进行算术运算,可以使用该工具。
awk 'BEGIN{ ere="[0-9][0-9]/[A-Z][a-z][a-z]/[0-9][0-9][0-9][0-9]" }
(match([=10=],ere)){ date=substr([=10=],RSTART,RLENGTH); a[date]++; n++ }
END { for (date in a) {
yyyy=substr(date,8,4);
mm=(index("JanFebMarAprMayJunJulAugSepOctNovDec",substr(date,4,3))+2)/3
mm=sprintf("%0.2d",mm)
dd=substr(date,1,2)
print a[date],a[date]/n,yyyy"-"mm"-"dd
}
}' log.txt
正如您所说,您只想使用 Linux/Unix Shell 命令执行此操作,我可以自由假设您的意思是 bash。 shell 还有很多其他类型,但让我们以最常见的一种为例。
简而言之,不,这是不可能的。 bash 不支持浮点运算,但你可以伪造它。示例:
$ echo $(( 2/3 ))
1
$ printf "%f\n" "$(( 10**15 * 2 / 3 ))E-15"
0.666667
所以假设你有你的呈现输出并且假设你必须总计,你可以这样做:
# total number of dates
n=3417
grep -E [0-9][0-9]/[A-Z]{1}[a-z]{2}/[0-9]{4} log.txt | sed 's/.*\(..\)\/Oct\/\(....\).*/-10-/' | sort | uniq -c | sort -ru | head -10 | \
while read -r count date; do
printf "%f %d %s\n" "$(( 10**15 * count / n ))E-15" "$count" "$date"
done
我有 Apache 网络服务器的访问日志文件。使用 Linux/UNIX shell 命令我计算了文件中唯一日期的数量。命令 uniq -c
返回文件中每个唯一日期的出现次数。是否可以对 uniq -c
返回的值进行算术运算,或者是否有任何其他方法来计算出现次数并进行算术运算?这是我的 Linux commads:
grep -E [0-9][0-9]/[A-Z]{1}[a-z]{2}/[0-9]{4} log.txt | sed 's/.*\(..\)\/Oct\/\(....\).*/-10-/' | sort | uniq -c | sort -ru | head -10
这里是输出:
358 2006-10-09
348 2006-10-10
347 2006-10-01
344 2006-10-20
339 2006-10-25
337 2006-10-24
337 2006-10-12
336 2006-10-06
336 2006-10-02
335 2006-10-19
您可能对单个 awk script that does all the above in a single go (with exception of the sorting). Also, awk 感兴趣,如果您想进行算术运算,可以使用该工具。
awk 'BEGIN{ ere="[0-9][0-9]/[A-Z][a-z][a-z]/[0-9][0-9][0-9][0-9]" }
(match([=10=],ere)){ date=substr([=10=],RSTART,RLENGTH); a[date]++; n++ }
END { for (date in a) {
yyyy=substr(date,8,4);
mm=(index("JanFebMarAprMayJunJulAugSepOctNovDec",substr(date,4,3))+2)/3
mm=sprintf("%0.2d",mm)
dd=substr(date,1,2)
print a[date],a[date]/n,yyyy"-"mm"-"dd
}
}' log.txt
正如您所说,您只想使用 Linux/Unix Shell 命令执行此操作,我可以自由假设您的意思是 bash。 shell 还有很多其他类型,但让我们以最常见的一种为例。
简而言之,不,这是不可能的。 bash 不支持浮点运算,但你可以伪造它。示例:
$ echo $(( 2/3 ))
1
$ printf "%f\n" "$(( 10**15 * 2 / 3 ))E-15"
0.666667
所以假设你有你的呈现输出并且假设你必须总计,你可以这样做:
# total number of dates
n=3417
grep -E [0-9][0-9]/[A-Z]{1}[a-z]{2}/[0-9]{4} log.txt | sed 's/.*\(..\)\/Oct\/\(....\).*/-10-/' | sort | uniq -c | sort -ru | head -10 | \
while read -r count date; do
printf "%f %d %s\n" "$(( 10**15 * count / n ))E-15" "$count" "$date"
done