2

ファイル内のすべての単語の出現回数をカウントしたいのですが、結果が間違っています。

#!/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
4

1 に答える 1

2

使用declare -a dictとは、各キーが数値に評価され、それがインデックスとして使用されることを意味します。あなたが言葉で物事を保存しているなら、それはあなたが望むものではありません。declare -A代わりに使用してください。


また、$[ ]数学の非常に時代遅れの構文です。最新のPOSIXshでさえ$(( ))、代わりに使用する必要があるをサポートしています。

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"
于 2012-09-03T04:01:50.850 に答える