Bash
輸出平均值的 Shell 程序
我需要做的是編寫一個名為 avgs 的 shell 程序,它會從文件中讀取帶有數據的行,其中標題行可以位於數據中的任何行。
我必須為最後 2 列中的每一列保留一個總計和計數,並且不得在總計和計數中包含來自第一行的數據。
這是包含數據的文件:
92876035 SMITZ S 15 26 95908659 CHIANG R 10 29 SID LNAME I T1/20 T2/30 92735481 BRUCE. R 16 28 93276645 YU C 17 27 91234987 MYRTH R 15 16
shell 程序將向標準輸出寫入以下行:“平均值為 17 和 24”
這是我嘗試過的,但它不起作用
count_ppl=0 total=0 while read ?? ?! do total=$((sum+b)) count_ppl=$((count_ppl+1)) done < filename avg=$(echo "scale=2;$total/$count_ppl" | bc) echo "The averages are = $avg"
這 ”??” 和 ”?!” 是否在“閱讀時”旁邊,因為我不知道該放什麼。
我想這可能計算一列的一個平均值,但是我將如何從列中獲取數據併計算兩個平均值。
(這是 bash 順便說一句)。
不確定您所說的“並且不得在總數和計數中包含第一行的數據”是什麼意思。您的意思是必須排除“92876035 SMITZ S 15 26”行還是不要“求和”“SID LNAME I T1/20 T2/30”?
??
and?!
需要替換為您需要的變數名。最後提到的變數名稱將保留輸入的其餘部分。您需要最後兩列,因此在您的情況下有 5 列,while read
語句可能是:while read col1 col2 col3 col4 col5
接下來,您需要檢查該行是否為標題行。在這種情況下,我將在第一列中測試 SID 一詞:
if [ "$col1" != 'SID' ]
從這裡我們可以開始計算:
totallines=$((totallines+1)) sumcol4=$((sumcol4+col4)) sumcol5=$((sumcol5+col5))
最後,您可以使用計算平均值
avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc) avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)
要結束它,您可以使用以下腳本:
#!/bin/bash while read col1 col2 col3 col4 col5 do if [ "$col1" != 'SID' ] then totallines=$((totallines+1)) sumcol4=$((sumcol4+col4)) sumcol5=$((sumcol5+col5)) fi done < /path/to/inputfile avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc) avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc) printf "The averages are %s and %s" $avgcol4 $avgcol5
另一種方法是使用
awk
:awk '{ if ( $1 != "SID" ) { COL4+=$4; COL5+=$5; } } END { LINES=NR-1; printf "The averages are %.2f and %.2f\n", COL4/LINES, COL5/LINES }' < /path/to/inputfile
上面的命令過濾標題行,否則將第 4 列和第 5 列相加,在處理輸入文件後,它將 LINES 變數設置為減去 1 的記錄數(標題行)並列印輸出行。
bash
和版本都awk
將輸出:The averages are 14.60 and 25.20