与えられたファイルから各生徒の総点を見つける

与えられたファイルから各生徒の総点を見つける

文書:

Name: Rad
Eng: 94
Tam: 98
Mat: 98
Soc: 98
Sci: 80
Name: Din
Eng: 87
Tam: 89
Mat: 78
Soc: 87
Sci: 34
Name: Hardy
Eng: 78
Tam: 87
Mat: 23
Soc: 34
Sci: 98

スクリプト:

#!/bin/bash
file=$1
num=$2
n=`wc -l < $file`
it=$((n/num))
echo $n
echo $it
awk -v numm="$num" '{if (NR<=numm){T+=$2}}END{print T}' $file

上記のスクリプトは、最初の生徒の総数を生成できます。また、残りの二人の生徒の総点も手に入れたいです。誰かが私を助けることができますか?

答え1

awk '/^Name:/ { if (name) printf("%s, score = %d\n", name, score); name = $2; score = 0; next }
              { score += $2 }
     END      { printf("%s, score = %d\n", name, score) }' file

結果:

Rad, score = 468
Din, score = 375
Hardy, score = 320

awk文字列で始まるすべての行に対して最初のブロックを実行しますName:。変数に値がある場合、name前の生徒の総点はその生徒の名前で印刷されます。その後、名前は現在の行の2番目のフィールドに設定され、スコアはゼロにリセットされます。その後、スクリプトはすぐに次の入力行に進みます。

第2のブロックは、前のブロックで処理されなかった入力の各行に対して実行される。score変数値にスコアを追加するだけです。

最後のブロックはファイルの最後の行を読み取った後に実行され、最初のブロックで実行された出力をエミュレートします。最後の学生の結果を出力することです。


コードをコピーするのは面倒なので、出力を実行する関数を使用するソリューションは次のとおりです。

awk 'function output() { if (name) printf("%s, score = %d\n", name, score) } 
     /^Name:/          { output(); name = $2; score = 0; next }
                       { score += $2 }
     END               { output() }' file

これは質問の一部ではありませんが、興味深いことがあります。

awk 'function output() { if (name) printf("%s\t score = %3d, mean = %.1f\n", name, score, score/count) } 
     /^Name:/          { output(); name = $2; score = count = 0; next }
                       { score += $2; ++count }
     END               { output() }' file

出力:

Rad      score = 468, mean = 93.6
Din      score = 375, mean = 75.0
Hardy    score = 320, mean = 64.0

答え2

検索できName、1​​つが見つかるたびに次の行にnumm移動してスコアを合計します。

#!/bin/bash
file=$1
num=$2
awk -v numm="$num" '
/Name/{
  mark = 0;
  printf("%s ",$2);
  for ( i=0; i<numm ; i++){
    getline;
    mark += $2;
  }
  printf("%d\n", mark);
}' $file

結果:

Rad 468
Din 375
Hardy 320

答え3

同じ効果を得るには、次のコマンドを見つけます。

注文する:

 for i in Rad Din Hardy
> do
> sed -n "/$i/,+5p" p.txt| awk -F ":" '{print $2}'| sed "/$i/d"| awk -v i="$i" 'BEGIN{sum=0}{sum=sum+$1}END {print "Total marks of " i " "  sum}'
> done

出力

Total marks of Rad 468
Total marks of Din 375
Total marks of Hardy 320

関連情報