Shell program that outputs the averages
What I need to do is write a shell program called avgs that would read lines from the file with data, where the title line could be at any line within the data.
I must keep a total and count for each of the last 2 columns and must not include data from the first line in the totals and counts.
This is the file with the data:
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
The shell program will write to stdout the line: "The averages are 17 and 24"
This is what I tried but it doesn't work
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"
The "??" and "?!" are there beside the "while read" because I do not know what to put there.
I guess this probably computes one averages for one column, but how would I get the data from the columns and compute two averages.
(this is bash btw).
bash shell-script text-processing numeric-data
add a comment |
What I need to do is write a shell program called avgs that would read lines from the file with data, where the title line could be at any line within the data.
I must keep a total and count for each of the last 2 columns and must not include data from the first line in the totals and counts.
This is the file with the data:
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
The shell program will write to stdout the line: "The averages are 17 and 24"
This is what I tried but it doesn't work
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"
The "??" and "?!" are there beside the "while read" because I do not know what to put there.
I guess this probably computes one averages for one column, but how would I get the data from the columns and compute two averages.
(this is bash btw).
bash shell-script text-processing numeric-data
Is result 17 a typo?
– Cyrus
Feb 25 '16 at 6:19
i'm pretty sure, I did the calculation myself it I got different numbers. The number are from the question
– shawn edward
Feb 25 '16 at 6:53
add a comment |
What I need to do is write a shell program called avgs that would read lines from the file with data, where the title line could be at any line within the data.
I must keep a total and count for each of the last 2 columns and must not include data from the first line in the totals and counts.
This is the file with the data:
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
The shell program will write to stdout the line: "The averages are 17 and 24"
This is what I tried but it doesn't work
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"
The "??" and "?!" are there beside the "while read" because I do not know what to put there.
I guess this probably computes one averages for one column, but how would I get the data from the columns and compute two averages.
(this is bash btw).
bash shell-script text-processing numeric-data
What I need to do is write a shell program called avgs that would read lines from the file with data, where the title line could be at any line within the data.
I must keep a total and count for each of the last 2 columns and must not include data from the first line in the totals and counts.
This is the file with the data:
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
The shell program will write to stdout the line: "The averages are 17 and 24"
This is what I tried but it doesn't work
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"
The "??" and "?!" are there beside the "while read" because I do not know what to put there.
I guess this probably computes one averages for one column, but how would I get the data from the columns and compute two averages.
(this is bash btw).
bash shell-script text-processing numeric-data
bash shell-script text-processing numeric-data
edited 22 mins ago
Rui F Ribeiro
40.1k1479135
40.1k1479135
asked Feb 25 '16 at 5:07
shawn edwardshawn edward
110613
110613
Is result 17 a typo?
– Cyrus
Feb 25 '16 at 6:19
i'm pretty sure, I did the calculation myself it I got different numbers. The number are from the question
– shawn edward
Feb 25 '16 at 6:53
add a comment |
Is result 17 a typo?
– Cyrus
Feb 25 '16 at 6:19
i'm pretty sure, I did the calculation myself it I got different numbers. The number are from the question
– shawn edward
Feb 25 '16 at 6:53
Is result 17 a typo?
– Cyrus
Feb 25 '16 at 6:19
Is result 17 a typo?
– Cyrus
Feb 25 '16 at 6:19
i'm pretty sure, I did the calculation myself it I got different numbers. The number are from the question
– shawn edward
Feb 25 '16 at 6:53
i'm pretty sure, I did the calculation myself it I got different numbers. The number are from the question
– shawn edward
Feb 25 '16 at 6:53
add a comment |
1 Answer
1
active
oldest
votes
Not sure what you mean by "and must not include data from the first line in the totals and counts.". Do you mean that the row "92876035 SMITZ S 15 26" must be excluded or just not to 'sum' "SID LNAME I T1/20 T2/30"?
The ??
and ?!
needs to be replaced by variable names you need. The last variable name mentioned will keep the remainder of the input. You need the last two columns so in your case there are 5 columns and the while read
statement could be:
while read col1 col2 col3 col4 col5
Next you need to check if the line is the title line. In this case I will test for the word SID in the first column:
if [ "$col1" != 'SID' ]
and from here we can start calculating:
totallines=$((totallines+1))
sumcol4=$((sumcol4+col4))
sumcol5=$((sumcol5+col5))
Finally you can calculate the averages using
avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc)
avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)
to wrap this up you can use the following script:
#!/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
Another way of doing this is to use awk
:
awk '{ if ( $1 != "SID" ) { COL4+=$4; COL5+=$5; } } END { LINES=NR-1; printf "The averages are %.2f and %.2fn", COL4/LINES, COL5/LINES }' < /path/to/inputfile
The above command filters for the title row, otherwise sum column 4 and column 5, and after processing the inputfile it will set the LINES variable to the number of record substracted by 1 (the title row) and prints the output line.
Both the bash
and the awk
version will output:
The averages are 14.60 and 25.20
I feel like this would work but for some reason, its not finding my file.
– shawn edward
Feb 25 '16 at 20:10
Nvm it works, seems like I need to give the absolute path to the file
– shawn edward
Feb 25 '16 at 20:18
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f265641%2fshell-program-that-outputs-the-averages%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Not sure what you mean by "and must not include data from the first line in the totals and counts.". Do you mean that the row "92876035 SMITZ S 15 26" must be excluded or just not to 'sum' "SID LNAME I T1/20 T2/30"?
The ??
and ?!
needs to be replaced by variable names you need. The last variable name mentioned will keep the remainder of the input. You need the last two columns so in your case there are 5 columns and the while read
statement could be:
while read col1 col2 col3 col4 col5
Next you need to check if the line is the title line. In this case I will test for the word SID in the first column:
if [ "$col1" != 'SID' ]
and from here we can start calculating:
totallines=$((totallines+1))
sumcol4=$((sumcol4+col4))
sumcol5=$((sumcol5+col5))
Finally you can calculate the averages using
avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc)
avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)
to wrap this up you can use the following script:
#!/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
Another way of doing this is to use awk
:
awk '{ if ( $1 != "SID" ) { COL4+=$4; COL5+=$5; } } END { LINES=NR-1; printf "The averages are %.2f and %.2fn", COL4/LINES, COL5/LINES }' < /path/to/inputfile
The above command filters for the title row, otherwise sum column 4 and column 5, and after processing the inputfile it will set the LINES variable to the number of record substracted by 1 (the title row) and prints the output line.
Both the bash
and the awk
version will output:
The averages are 14.60 and 25.20
I feel like this would work but for some reason, its not finding my file.
– shawn edward
Feb 25 '16 at 20:10
Nvm it works, seems like I need to give the absolute path to the file
– shawn edward
Feb 25 '16 at 20:18
add a comment |
Not sure what you mean by "and must not include data from the first line in the totals and counts.". Do you mean that the row "92876035 SMITZ S 15 26" must be excluded or just not to 'sum' "SID LNAME I T1/20 T2/30"?
The ??
and ?!
needs to be replaced by variable names you need. The last variable name mentioned will keep the remainder of the input. You need the last two columns so in your case there are 5 columns and the while read
statement could be:
while read col1 col2 col3 col4 col5
Next you need to check if the line is the title line. In this case I will test for the word SID in the first column:
if [ "$col1" != 'SID' ]
and from here we can start calculating:
totallines=$((totallines+1))
sumcol4=$((sumcol4+col4))
sumcol5=$((sumcol5+col5))
Finally you can calculate the averages using
avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc)
avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)
to wrap this up you can use the following script:
#!/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
Another way of doing this is to use awk
:
awk '{ if ( $1 != "SID" ) { COL4+=$4; COL5+=$5; } } END { LINES=NR-1; printf "The averages are %.2f and %.2fn", COL4/LINES, COL5/LINES }' < /path/to/inputfile
The above command filters for the title row, otherwise sum column 4 and column 5, and after processing the inputfile it will set the LINES variable to the number of record substracted by 1 (the title row) and prints the output line.
Both the bash
and the awk
version will output:
The averages are 14.60 and 25.20
I feel like this would work but for some reason, its not finding my file.
– shawn edward
Feb 25 '16 at 20:10
Nvm it works, seems like I need to give the absolute path to the file
– shawn edward
Feb 25 '16 at 20:18
add a comment |
Not sure what you mean by "and must not include data from the first line in the totals and counts.". Do you mean that the row "92876035 SMITZ S 15 26" must be excluded or just not to 'sum' "SID LNAME I T1/20 T2/30"?
The ??
and ?!
needs to be replaced by variable names you need. The last variable name mentioned will keep the remainder of the input. You need the last two columns so in your case there are 5 columns and the while read
statement could be:
while read col1 col2 col3 col4 col5
Next you need to check if the line is the title line. In this case I will test for the word SID in the first column:
if [ "$col1" != 'SID' ]
and from here we can start calculating:
totallines=$((totallines+1))
sumcol4=$((sumcol4+col4))
sumcol5=$((sumcol5+col5))
Finally you can calculate the averages using
avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc)
avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)
to wrap this up you can use the following script:
#!/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
Another way of doing this is to use awk
:
awk '{ if ( $1 != "SID" ) { COL4+=$4; COL5+=$5; } } END { LINES=NR-1; printf "The averages are %.2f and %.2fn", COL4/LINES, COL5/LINES }' < /path/to/inputfile
The above command filters for the title row, otherwise sum column 4 and column 5, and after processing the inputfile it will set the LINES variable to the number of record substracted by 1 (the title row) and prints the output line.
Both the bash
and the awk
version will output:
The averages are 14.60 and 25.20
Not sure what you mean by "and must not include data from the first line in the totals and counts.". Do you mean that the row "92876035 SMITZ S 15 26" must be excluded or just not to 'sum' "SID LNAME I T1/20 T2/30"?
The ??
and ?!
needs to be replaced by variable names you need. The last variable name mentioned will keep the remainder of the input. You need the last two columns so in your case there are 5 columns and the while read
statement could be:
while read col1 col2 col3 col4 col5
Next you need to check if the line is the title line. In this case I will test for the word SID in the first column:
if [ "$col1" != 'SID' ]
and from here we can start calculating:
totallines=$((totallines+1))
sumcol4=$((sumcol4+col4))
sumcol5=$((sumcol5+col5))
Finally you can calculate the averages using
avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc)
avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)
to wrap this up you can use the following script:
#!/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
Another way of doing this is to use awk
:
awk '{ if ( $1 != "SID" ) { COL4+=$4; COL5+=$5; } } END { LINES=NR-1; printf "The averages are %.2f and %.2fn", COL4/LINES, COL5/LINES }' < /path/to/inputfile
The above command filters for the title row, otherwise sum column 4 and column 5, and after processing the inputfile it will set the LINES variable to the number of record substracted by 1 (the title row) and prints the output line.
Both the bash
and the awk
version will output:
The averages are 14.60 and 25.20
edited Feb 25 '16 at 7:41
answered Feb 25 '16 at 7:21
LambertLambert
9,00721228
9,00721228
I feel like this would work but for some reason, its not finding my file.
– shawn edward
Feb 25 '16 at 20:10
Nvm it works, seems like I need to give the absolute path to the file
– shawn edward
Feb 25 '16 at 20:18
add a comment |
I feel like this would work but for some reason, its not finding my file.
– shawn edward
Feb 25 '16 at 20:10
Nvm it works, seems like I need to give the absolute path to the file
– shawn edward
Feb 25 '16 at 20:18
I feel like this would work but for some reason, its not finding my file.
– shawn edward
Feb 25 '16 at 20:10
I feel like this would work but for some reason, its not finding my file.
– shawn edward
Feb 25 '16 at 20:10
Nvm it works, seems like I need to give the absolute path to the file
– shawn edward
Feb 25 '16 at 20:18
Nvm it works, seems like I need to give the absolute path to the file
– shawn edward
Feb 25 '16 at 20:18
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f265641%2fshell-program-that-outputs-the-averages%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Is result 17 a typo?
– Cyrus
Feb 25 '16 at 6:19
i'm pretty sure, I did the calculation myself it I got different numbers. The number are from the question
– shawn edward
Feb 25 '16 at 6:53