내가 해야 할 일은 파일에서 데이터가 포함된 행을 읽는 avgs라는 쉘 프로그램을 작성하는 것입니다. 여기서 헤더 행은 데이터의 어느 곳에나 있을 수 있습니다.
마지막 두 열의 합계를 계산하고 계산해야 하며 합계 및 계산에 첫 번째 행의 데이터를 포함하면 안 됩니다.
다음은 데이터가 포함된 파일입니다.
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
쉘 프로그램은 표준 출력에 다음 줄을 기록합니다: "Theaverage is 17 and 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"
"읽는 동안" 옆에 "??"와 "?!"가 있는 이유는 거기에 무엇을 넣어야 할지 모르기 때문입니다.
이것은 한 열의 하나의 평균을 계산할 수 있을 것 같지만 열에서 데이터를 가져와 두 개의 평균을 계산하려면 어떻게 해야 합니까?
(BTW, 이것은 bash입니다).
답변1
"첫 번째 행의 데이터는 합계 및 개수에 포함되어서는 안 됩니다"라는 말이 무슨 뜻인지 잘 모르겠습니다. "92876035 SMITZ S 15 26" 행을 제외해야 한다는 의미입니까, 아니면 "SID LNAME I T1/20 T2/30"이 "합계"되지 않았다는 의미입니까?
필요한 변수 이름으로 바꿔야 ??
합니다 . ?!
마지막으로 언급된 변수 이름은 나머지 입력을 보유합니다. 마지막 두 개의 열이 필요하므로 귀하의 경우에는 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
답변2
#!/usr/bin/awk -f
NR == 1 { next }
/^[^0-9]/ { next }
{
s1 += $(NF - 1)
s2 += $NF
++n;
}
END {
printf("The averages are %.2f and %.2f\n", s1/n, s2/n)
}
시험:
$ chmod +x avgs
$ ./avgs file
The averages are 14.50 and 25.00
awk
이는 데이터의 첫 번째 줄(질문에서 요청한 대로)과 첫 번째 문자로 숫자가 아닌 값이 포함된 모든 줄을 건너뛰는 데 사용됩니다 .
다른 모든 행의 경우 마지막 두 필드의 숫자를 twe sum에 추가하고 s1
counter s2
도 증가시킵니다 n
.
마지막으로 결과를 소수점 이하 두 자리까지 출력합니다.
쉘의 "라인"으로:
$ awk 'NR==1||/^[^0-9]/{next} {s1+=$(NF-1);s2+=$NF;++n} END {printf("The averages are %.2f and %.2f\n", s1/n, s2/n)}' file
The averages are 14.50 and 25.00
관련된: