テキストファイルの一意のコレクション数を数えるシェルスクリプト

テキストファイルの一意のコレクション数を数えるシェルスクリプト

私は与えられたテキストファイルを取得し、文字数、コレクション数、各コレクション数を数えるスクリプトを書いています。最初の部分は簡単ですが、ループに問題があります。私の理解は、myStringの数がループの数になるということです。文字が読み取られるたびにif / elifステートメントを介してコレクションと一致すると、そのコレクションに対応する変数の値を1ずつ増やします。

Shellcheck.netは私の行が好きではありませんが、その理由を理解できません。

#!/bin/bash

myString=$(cat sampletext.txt | tr A-Z a-z)   #this works
count=$(echo -n "$myString" |tr -d '[.]'| wc -c)    #this works
vowels=$(echo -n $myString | tr -cd 'aeiou'| wc -c) #this works

va=0
ve=0
vi=0
vo=0
vu=0
i=0
while (( i++ < ${#myString} )); do
char=$(expr substr "$myString" "$i" 1)
if   [ "$char" -eq "a" ]; then
((va=++))
elif [ "$char" -eq "e" ]; then
((ve=++))
elif [ "$char" -eq "i" ]; then
((vi=++))
elif [ "$char" -eq "o" ]; then
((vo=++))
elif [ "$char" -eq "u" ]; then
((vu=++))
fi
done
echo $vi

シェル検査出力:

((va=++))
^-- SC1105 (error): Shells disambiguate (( differently or not at all. For subshell, add spaces around ( . For ((, fix parsing errors.
  ^-- SC2030 (info): Modification of va is local (to subshell caused by (..) group).

*残念ながら、ダメな部分だけ入れました。 Shebangを含むコンテンツ全体を表示するように編集しました=)

ベストアンサー1

awk基本的なソリューションを提供する予定です。あなたが言及したあなたが欲しい」作成したいレポートを作成するためにループを使用する方法を学び、理解しています」awk、これは通常純粋よりもこの場合より効率的です。bash

#!/bin/sh
#
grep -o -- . "$1" |
    awk '
        /[[:alpha:]]/ { letters[tolower($1)]++ }
        /[aeiou]/ { vowels++ }

        END {
            printf "%d\tvowels\n", vowels;
            for (letter in letters) {
                printf "%d\t%s\n", letters[letter], letter | "sort -k2,3"
            }
        }
    '

ファイルを呼び出しlettersて実行可能にします(chmod a+x letters)。入力ファイルはsampletext.txt次のように実行できます

./letters sampletext.txt

ノート

  • grep -o -- . {file}(GNUgrepまたは互換性があると仮定)ファイルを1行に1つずつ別々の文字に分割します。awk内部でこれを行うこともできますが、これは迅速で怠惰な方法です。
  • [[:alpha:]]アルファベット文字と一致します。[[:alnum:]]英数字または.任意の文字を使用できます。
  • このprintf | "sort"構成は、書式設定されたすべての出力をコマンド(単一インスタンス)に供給し、コマンドsortは現在のロケールに基づいて列2に基づいてソートします。

おすすめ記事