2012-09-03 131 views
2

我想统计文件中每个字的出现次数 但结果是错误的。使用bash统计文件中每个字的出现次数

#!/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 
+0

这是功课? – Steve

+0

@steve不,我正在学习自己。我只是想用bash解决这个问题 – bopie

+0

使用调试跟踪的一个好主意,现在看看你的调试跟踪显示了什么。为什么它会将正在阅读的每个单词的“dict [$ word] ='右边的值增加1?那不是你想要的,是吗?最后,您的调试循环最后也是一个好主意,但是输出再次显示您的变量命名/分配/取消引用正如您所期望的那样工作。祝你好运。 – shellter

回答

2

使用declare -a dict意味着每个键被计算为一个数值,然后用作索引。这不是你想要的,如果你是通过文字存储的东西。改为使用declare -A


此外,$[ ]是数学一个非常过时的语法。即使是现代的POSIX sh的支持$(()),你应该使用:

dict[$word]=$((${dict[$word]} + 1)) 

,或者利用庆典,只有数学语法:

((dict[$word]++)) 

此外,使用for word in $(cat $1)在几个被打破方式:

  • 它不引用$1,所以对于一个文件名与空格,它会将名称分成几个单词,并尝试将每个单词作为单独的文件打开。为了解决这个问题,你可以使用$(cat "$1")$(<"$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" 
+0

。主要问题是“声明 - 一个字典”。我从你的答案中学到很多东西。非常感谢你。 – bopie

+0

@ 4E5043如果这对您有帮助,请将其标记为已接受。 –

+0

虽然'$((...))'(算术扩展)是POSIX,但是复合命令'((...))'不是。 – chepner

相关问题