SHELL 统计文档中的单词或者字符出现的次数
shell也有Map的 数据结构。 类似其他语言的键值对(字典)等。
Bash支持关联数组,它可以使用字符串作为数组索引,有时候采用字符串索引更容易理解。
1 定义关联数组
1) 首先需要使用声明语句将一个变量声明为关联数组。
xiaosi@Qunar:~$ declare-A assArray
2)利用内嵌索引-值列表的方法
xiaosi@Qunar:~$ assArray=([lucy]=beijing [yoona]=shanghai)
xiaosi@Qunar:~$ echo
${assArray[lucy]}
beijing
3) 使用独立的索引-值进行赋值
xiaosi@Qunar:~$ assArray[lily]=shandong
xiaosi@Qunar:~$ assArray[sunny]=xian
xiaosi@Qunar:~$ echo
${assArray[sunny]}
xian
xiaosi@Qunar:~$ echo
${assArray[lily]}
shandong
利用这个特性就可以统计字符串(单词)或者字符的个数。
我们以 Linux /etc/passwd 文件来做例子:
2. 统计每个单词出现次数,本例子是以分隔符:做的示例
[root@nat1 ~]# awk -F":" '{for (i=1;i<=NF;i++) {a[$i]++}}END {for (i in a) print i,a[i]}' /etc/passwd
- awk 以:为分隔符号,通过$1--$7来代表各个单词
- 对每个单词作为数组a的下标, 每次出现一个就累加一次++
- 打印每个单词(数组的下标i),以及每隔单词出现的次数a[i]
3. 统计每个字符出现次数
3.1 将单词变成字符的方法
- 方法1: echo "range" | sed 's/./& /g' #每个字符替换成“这个字符+空格
- 方法2: echo "range" | sed 's/\(.\)/\1 /g' #BRE正则表达式
- 方法3: echo "range" | sed -r 's/(.)/\1 /g' #ERE正则表达式
- 方法4: echo "range" | grep -o . | tr '\n' ' ' #每个字母(.)通过grep -o提取出来
3.2 统计字符出现的次数
[root@nat1 ~]# sed -r 's/(.)/\1 /g' /etc/passwd | awk -F" " '{for (i=1;i<=NF;i++) {a[$i]++}}END {for (i in a) print i,a[i]}' | sort -n -k 2 -r
: 114
n 70
/ 70
o 66
s 53
i 51
b 32
l 31
a 29
t 26
r 25
e 23
x 21
g 21
d 19
m 17
9 17
p 16
1 12
y 11
h 11
0 9
v 8
8 7
u 6
2 6
w 5
f 5
c 5
4 5
k 4
7 4
S 3
U 2
P 2
N 2
6 2
5 2
- 2
T 1
M 1
H 1
F 1
3 1
唯一需要解释的就是把单词转变成字符,然后统计,结果按照出现的次数的降序排列。