ファイル内の文字数の計算中にエラーが発生しました。

ファイル内の文字数の計算中にエラーが発生しました。

ファイル内の複数の単語と文字を見つけるためのソースコードがあります。

#!/bin/bash
w=0
cc=0
for i in `cat $1`
do
j=$i
echo $j
w=$(($w+1))
c=`expr $j:'.*'`
cc=$(($cc+$c))
done
echo "no of characters"  $cc
echo "no of words" $w

ただし、端末で実行すると、次のエラーメッセージが表示されます。 ^ ./countWordChar 1.c hello ./countWordChar: line 10: 0+hello:.*: 式の構文エラー (エラーフラグは":.*") 文字数 0 単語数 1

コードの10行はですcc=$(($cc+$c))。明らかに、c変数の値は単語の文字数ではなく、単語自体です。

私の1.cファイルの内容は次のとおりです。

hello world
hello

コードに問題がありますか?

PS。ファイル内の文字数を計算するコマンドが組み込まれていることはわかっていますが、操作に応じて古いコードを使用する必要があります。

答え1

ユーティリティexprは引数を式に解析します。演算子は独立引数としてマークする必要があります。

expr "$j" : '.*'

上記には、およびコンテンツのexpr4つのパラメータが渡されます。exprコンテンツがor(または一部の実装では同様のもの)ではないと仮定すると、パターンマッチング演算子が適用されるコンテンツとして使用されます。$j:.*$j(!lengthexpr:$j

より強力にするには、次のものが必要です。

expr " $j" : '.*' - 1

(空白で始まる2番目の引数はexpr演算子として認識されないため、上記の問題は解決されます。)

そして

expr $j:'.*'

これは2つの引数になります(そしてexpr次の内容(スペースやワイルドカードが含まれていないと仮定し、以下を参照))。 (コマンド名に加えて)引数が1つだけ表示されるため、操作は要求されません。これはエコー専用の文字列引数にすぎません。$j:.*$jexprexpr

今、コードには他の多くの問題があります。

変数の拡張とコマンドの置き換え($((...))または`...`未使用の形式)、引用されていない経験があるときsplit+globsplitセクションの一部`cat $1`(でなければならない$(cat < "$1"))を単語に分割したいが、glob部分は望ましくありません。それ以外の場合は、*現在のディレクトリのファイルのリストに単語を展開する必要があります。他のすべての変数拡張は引用する必要があります。必須ですが、引用符は問題ありません)。

返品、echo任意のデータと一緒に使用することはできません

したがって、次のようにする必要があります。

w=0 c=0
set -f #  disable glob
for i in $(cat < "$1"); do
  printf '%s\n' "$i"
  w="$((w + 1))"
  c="$(expr " $i" : '.*' + "$c" - 1)"
done

答え2

コマンドはexpr $j:'.*'1つexprのパラメータを受け取ります。
コマンドはexprこれを理解していません。

このコマンドはexpr各パラメータを明確に区別する必要があります。

expr "$j" ":" '.*'

これはコマンドに提供される3つのパラメータですexpr"周辺引用符は:実際には必要ありません。$j誤解を避けるために、文字列の前にスペースを使用することをお勧めします。

expr " $j" : '.*'

これにより、スクリプトは次のようになります。

#!/bin/dash
w=0    cc=0
for i in `cat $1`; do
    echo "$j"
    w=$(($w+1))
    c=`expr " $i" : '.*'`
    cc=$((cc+c))
done
echo "no of characters"  $cc
echo "no of words" $w

しかし、これはbashスクリプトではなくダッシュスクリプトに近いです(これは質問にタグを付ける方法です)。
単純化されたbashスクリプトは次のとおりです。

#!/bin/bash
w=0    cc=0
for i in $(< $1)
do
    ((w++))
    cc=((cc+${#i}))
done
echo "no of characters"  "$cc"
echo "no of words" "$w"

同じですが、少し$(< $1)速いです$(cat $1)。 wを増やすには、より短いを使用してくださいw++。文字数を計算するには、$i長さをasとして使用できます${#i}

またはより短く:

#!/bin/bash
w=0    cc=0
for i in $(< $1)
do  (( w++ , cc += ${#i} ))
done
printf "no of characters %s\nno of words %s\n"  "$cc" "$w"

bash(2.04-devel以降)を使用してコンマ演算子を,使用します。cc += ${#i}cc = cc + ${#i}

関連情報