我想计算文件中每个单词的出现次数
但结果是错误的。
#!/bin/bash
#usage: count.sh file
declare -a dict
for word in $(cat $1)
do
if [ ${dict[$word]} == "" ] ;then
dict[$word]=0
else
dict[$word]=$[${dict[$word]} + 1]
fi
done
for word in ${!dict[@]}
do
echo $word: ${dict[$word]}
done
使用下面的测试文件:
learning the bash shell
this is second line
this is the last line
bash -x count.sh 文件
得到结果:
+ declare -a dict
++ cat book
+ for word in '$(cat $1)'
+ '[' '' == '' ']'
+ dict[$word]=0
+ for word in '$(cat $1)'
+ '[' 0 == '' ']'
+ dict[$word]=1
+ for word in '$(cat $1)'
+ '[' 1 == '' ']'
+ dict[$word]=2
+ for word in '$(cat $1)'
+ '[' 2 == '' ']'
+ dict[$word]=3
+ for word in '$(cat $1)'
+ '[' 3 == '' ']'
+ dict[$word]=4
+ for word in '$(cat $1)'
+ '[' 4 == '' ']'
+ dict[$word]=5
+ for word in '$(cat $1)'
+ '[' 5 == '' ']'
+ dict[$word]=6
+ for word in '$(cat $1)'
+ '[' 6 == '' ']'
+ dict[$word]=7
+ for word in '$(cat $1)'
+ '[' 7 == '' ']'
+ dict[$word]=8
+ for word in '$(cat $1)'
+ '[' 8 == '' ']'
+ dict[$word]=9
+ for word in '$(cat $1)'
+ '[' 9 == '' ']'
+ dict[$word]=10
+ for word in '$(cat $1)'
+ '[' 10 == '' ']'
+ dict[$word]=11
+ for word in '$(cat $1)'
+ '[' 11 == '' ']'
+ dict[$word]=12
+ for word in '${!dict[@]}'
+ echo 0: 12 0: 12
Using declare -a dict
意味着每个键都被评估为一个数值,然后将其用作索引。如果你用文字来存储东西,那不是你想要的。使用declare -A
反而。
Also, $[ ]
是一种非常过时的数学语法。甚至现代 POSIX sh 也支持$(( ))
,您应该使用它:
dict[$word]=$(( ${dict[$word]} + 1 ))
或者,利用仅 bash 的数学语法:
(( dict[$word]++ ))
另外,使用for word in $(cat $1)
有几个方面被破坏:
- 它没有引用
$1
,因此对于带有空格的文件名,它会将名称拆分为几个单词,并尝试将每个单词作为单独的文件打开。要仅修复此问题,您可以使用$(cat "$1")
or $(<"$1")
(这更有效,因为它不需要启动外部程序 cat)。
- 它尝试将文件中的单词扩展为全局变量——如果文件包含
*
,当前目录中的每个文件都将被视为一个单词。
相反,使用 while 循环:
while read -r -d' ' word; do
if [[ -n ${dict[$word]} ]] ; then
dict[$word]=$(( ${dict[$word]} + 1 ))
else
dict[$word]=1
fi
done <"$1"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)