I'm a bit confused by the done < $1
notation.
I'm trying to write a program "sumnums" that reads in a file called "nums" that has a couple rows of numbers. Then it should print out the rows of the numbers followed by a sum of all the numbers.
Currently I have:
#!/bin/bash
sum=0;
while read myline
do
echo "Before for; Current line: \"$myline\""
done
for i in $myline; do
sum=$(expr $sum + $i)
done < $1
echo "Total sum is: $sum"
and it outputs the list of the numbers from nums correctly then says ./sumnums: line 10: $1: ambiguous redirect
, then outputs Total sum is: 0
.
So somehow it isn't adding. How do I rearrange these lines to fix the program and get rid of the "ambiguous redirect"?
Assuming your filename is in $1
(that is, that your script was called with ./yourscript nums
):
#!/bin/bash
[[ $1 ]] || set -- nums ## use $1 if already set; otherwise, override with "nums"
sum=0
while read -r i; do ## read from stdin (which is redirected by < for this loop)
sum=$(( sum + i )) ## ...treat what we read as a number, and add it to our sum
done <"$1" ## with stdin reading from $1 for this loop
echo "Total sum is: $sum"
If $1
doesn't contain your filename, then use something that does contain your filename in its place, or just hardcode the actual filename itself.
Notes:
<"$1"
is applied to a while read
loop. This is essential, because read
is (in this context) the command that actually consumes content from the file. It can make sense to redirect stdin to a for
loop, but only if something inside that loop is reading from stdin. $(( ))
is modern POSIX sh arithmetic syntax. expr
is legacy syntax; don't use it. awk
to the rescue!
awk '{for(i=1;i<=NF;i++) sum+=$i} END{print "Total sum is: " sum}' file
bash
is not the right tool for this task.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.