- ユーザーに評価する論文の数を尋ねますか?
- 各論文の入力スコアを必要な回数だけ繰り返すforループを作成します。
- ユーザーに各スコア(1〜100)を尋ねます。
- ループ数の計算
- プログラムが終了すると、すべての試験紙の平均スコアが表示されます。
whileループを作成しましたが、forループを作成する方法がわかりません。
#!/bin/bash
set -x
count=0
papers=0
score=0
grade=0
average=0
read -p " How many papers would you like to grade? " papers
while [ $count -lt $papers ]
do
read -p " Please enter a score " grade
score=`expr $score + $grade`
count=$((count + 1))
done
average=`expr $score / $papers`
echo $average
答え1
指示を無視して、私が思ったように行います(どうせポイントを計算する必要がある場合(ポイント4)、ユーザーにポイント数(ポイント1)を尋ねる必要がないため、ガイドラインはとにかく偽です)。
awk 'BEGIN { printf("Enter scores, one per line, end with Ctrl+D\n") }
$1 < 1 || $1 > 100 { printf("Invalid score, must be [1,100]\n"); next }
{ sum += $1; n++ }
END { printf("Average: %.2f\n", sum/n) }'
テスト:
Enter scores, one per line, end with Ctrl+D
0
Invalid score, must be [1,100]
2
3
4
5
99
100
1001
Invalid score, must be [1,100]
Average: 35.50
これにより、スクリプトへのリダイレクトを使用してファイルからスコアを簡単に読み取ることができますawk
。
同様です/bin/sh
(ただし、整数ではなく入力/結果を処理しません)。
#!/bin/sh
echo 'Enter scores, one per line, end with Ctrl+D'
while read score; do
if [ "$score" -lt 1 ] || [ "$score" -gt 100 ]; then
echo 'Invalid score, must be [1,100]'
else
sum=$(( sum + score ))
n=$(( n + 1 ))
fi
done
printf 'Average: %d\n' "$(( sum / n ))"
分数の数に固執する場合は、範囲外の分数を異なる方法で処理する必要があります。
#!/bin/sh
printf 'Enter the number of scores that you will enter: ' >&2
read nscores
while [ "$nscores" -gt 0 ]; do
while true; do
read score
if [ "$score" -lt 1 ] || [ "$score" -gt 100 ]; then
echo 'Invalid score, must be [1,100]'
else
break
fi
done
sum=$(( sum + score ))
n=$(( n + 1 ))
nscores=$(( nscores - 1 ))
done
printf 'Average: %d\n' "$(( sum / n ))"
こんな、もう一つのwhile
サイクルですね。
シェルスクリプトでは、ループはfor
ファイル名のリストなどの明示的なリストにのみ使用されます。for
この問題を解決するためにシェルスクリプトを作成した場合は、この演習ではループを使用する必要はありません。
for
この練習の合理的なユースケースは、ループを使用して解決できます。
#!/bin/sh
for score do
if [ "$score" -lt 1 ] || [ "$score" -gt 100 ]; then
printf 'Invalid score (%d), must be [1,100]\n' "$score" >&2
else
sum=$(( sum + score ))
n=$(( n + 1 ))
fi
done
printf 'Average: %d\n' "$(( sum / n ))"
スクリプトはコマンドラインでスコアを受け入れます。
$ sh ./script.sh 1 20 10 22 3001 20
Invalid score (3001), must be [1,100]
Average: 14
スコアリストは静的リストなので、ループを使用して繰り返すのが適切ですfor
。
答え2
ちょうどwhileループをforループに変更したすべての操作はほぼ完了しました。
#!/bin/bash
set -x
declare -i score=0
declare -i grade=0
read -p " How many papers would you like to grade? " papers
for ((count=0; count<$papers; count++)) ;do
read -p " Please enter a score " grade
score=$(expr $score + $grade)
done
average=$(expr $score / $papers)
echo $average
答え3
あなたはすでに答えを受け入れていますが、私は少し違った視点を提示します。 Bashスクリプトで整数を繰り返す必要がある場合は、seq
Typeを使用できます。
$ man seq
コンソールでの仕組みをお読みください。
一行の例:
$ for i in $(seq 1 10); do echo $i; done
1
2
3
4
5
6
7
8
9
10
echo $i
タスクの論理だけを持つ代わりに