ForループLinuxスクリプト[閉じる]

ForループLinuxスクリプト[閉じる]
  1. ユーザーに評価する論文の数を尋ねますか?
  2. 各論文の入力スコアを必要な回数だけ繰り返すforループを作成します。
  3. ユーザーに各スコア(1〜100)を尋ねます。
  4. ループ数の計算
  5. プログラムが終了すると、すべての試験紙の平均スコアが表示されます。

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スクリプトで整数を繰り返す必要がある場合は、seqTypeを使用できます。

$ man seq

コンソールでの仕組みをお読みください。

一行の例:

$ for i in $(seq 1 10); do echo $i; done
1
2
3
4
5
6
7
8
9
10

echo $iタスクの論理だけを持つ代わりに

関連情報