Bash 从文件生成频率表
给定一个每行包含一个数字的输入文件,我如何计算该文件中某个项目出现的次数Bash 从文件生成频率表,bash,file,shell,awk,Bash,File,Shell,Awk,给定一个每行包含一个数字的输入文件,我如何计算该文件中某个项目出现的次数 cat input.txt 1 2 1 3 1 0 期望输出(=>[1,3,1,1]): 如果该解决方案还可以扩展为浮点数,那就太好了。您的意思是要计算一个项目在输入文件中出现的次数?首先对其进行排序(如果输入总是数字,则使用-n,如示例所示),然后计算唯一的结果 sort -n input.txt | uniq -c 至少有一部分是可以用计算机完成的 sort output.txt | uniq -c 但是计数的顺
cat input.txt
1
2
1
3
1
0
期望输出(=>[1,3,1,1]):
如果该解决方案还可以扩展为浮点数,那就太好了。您的意思是要计算一个项目在输入文件中出现的次数?首先对其进行排序(如果输入总是数字,则使用
-n
,如示例所示),然后计算唯一的结果
sort -n input.txt | uniq -c
至少有一部分是可以用计算机完成的
sort output.txt | uniq -c
但是计数的顺序是相反的。这将解决这个问题
sort test.dat | uniq -c | awk '{print $2, $1}'
另一种选择:
awk '{n[$1]++} END {for (i in n) print i,n[i]}' input.txt | sort -n > output.txt
除了其他答案之外,你还可以。(但这又不是直方图。) 用
-n
每个
$\uuu
数字递增哈希%h
一旦到达
input.txt的END
,
sort{$a$b}
hash的数字排序
打印编号$n
和频率$h{$n}
适用于浮点运算的类似代码:
perl -lne '$h{int($_)}++; END{for $n (sort {$a <=> $b} keys %h) {print "$n\t$h{$n}"}}' float.txt
jot -r 100.0 10 15 | numprocess /%10/ | maphimbu -s 1
输出:
0 1
1 3
2 1
3 1
使用Debian软件包中的maphimbu
:
输出:
1 20
2 21
3 20
4 21
5 18
1 21
1.1 17
1.2 14
1.3 18
1.4 11
1.5 19
maphimbu
也适用于浮点:
perl -lne '$h{int($_)}++; END{for $n (sort {$a <=> $b} keys %h) {print "$n\t$h{$n}"}}' float.txt
jot -r 100.0 10 15 | numprocess /%10/ | maphimbu -s 1
输出:
1 20
2 21
3 20
4 21
5 18
1 21
1.1 17
1.2 14
1.3 18
1.4 11
1.5 19
我有一个类似的问题,如前所述,但跨越千兆字节的gzip日志文件。因为这些解决方案中有很多都需要等待所有的数据被解析,所以我选择了基于regexp的编写来快速解析和聚合数据
在上述情况下,只需将数据传递给直方图函数即可:
rare histo input.txt
#或
cat input.txt |罕见历史
#产出:
1 3
0 1
2 1
3 1
但它也可以通过regex/表达式处理更复杂的情况,例如:
稀有历史--match“(\d+)”--提取“{1}”input.txt
我不知道uniq
命令。我将其更改为cat input.txt | sort-n | uniq-c | awk'{print$2”“$1}'
,现在我获得了所需的输出。您可以使用awk获得排序,但不需要在那里使用cat。您应该了解@Javier,'n'数组只保留它在输入文件中看到的字符串的计数。它可以是int、float或任意字符串。是的,“结束”部分在输入文件完全读取后执行。您不需要在awk中初始化变量:未初始化的变量被认为是零或空字符串(取决于上下文)。在本例中,“i”是一个循环变量。我认为默认的“排序”行为是考虑整条线。此解决方案适用于输入文件中的任何内容:awk数组是关联数组。感谢您使用基于awk的解决方案。据我所知,在第一部分中,考虑到列$1
中的元素,您将直方图
存储到n
数组中。END
部分的意思是,在构建柱状图之后将进行,对吗?对于awk
中的循环,是否不需要初始化变量i
?然后,sort-n
将仅应用于输出的第一列:i,n[i]
,对吗?i、 e不在n[i]
?此外,此解决方案仅适用于整数
数字(因为数组的索引)?awk
解决方案的显著优点是不需要排序
!要获得排序的输出,只需跟踪所看到的最大值和最小值,并对它们进行迭代,检查它们是否都在数组中。(这只适用于整数,而不适用于浮点数。)也适用于字符串!只需将第一个单词$1
更改为$0
,整行代码:awk'{n[$0]+}END{for(in n中的i)print i,n[i]}
可以让您轻松地查找和计算输入中的重复行。太棒了。我刚刚删除了一条评论,其中我说我在基于awk的解决方案中遇到了一个bug。实际上,这是我代码中的一个bug。由于其他人也可能这样做,我认为在这里分享我的经验可能会有用:我的问题是,可能受for循环的shell语法的影响,我在awk
命令的“END”部分的“for”和“print”之间添加了“;”。结果,for循环没有执行任何操作,而print操作只使用了i
的最后一个值。这种输出简单而有用,但不是直方图。例如,我同意你没有要求直方图。不过,这也可以通过bash
实现,这正是我来寻找的。请参阅此问题及其答案:如果第一列中的项目长度不同,这将使对齐有点混乱,因此在对列重新排序时可以使用制表符而不是默认空格:sort test.dat | uniq-c | awk'{print$2”\t“$1}'
排序键%h
使用字典排序;它不按数字排序。