Shell loops using non-integers?
I wrote a .sh file to compile and run a few programs for a homework assignment. I have a "for" loop in the script, but it won't work unless I use only integers:
#!/bin/bash
for (( i开发者_Go百科=10; i<=100000; i+=100))
do
./hw3_2_2 $i
done
The variable $i is an input for the program hw3_2_2, and I have non-integer values I'd like to use. How could I loop through running the code with a list of decimal numbers?
I find it surprising that in five years no one ever mentioned the utility created just for generating ranges, but, then again, it comes from BSD around 2005, and perhaps it wasn't even generally available on Linux at the time the question was made.
But here it is:
for i in $(seq 0 0.1 1)
Or, to print all numbers with the same width (by prepending or appending zeroes), use -w
. That helps prevent numbers being sent as "integers", if that would cause issues.
The syntax is seq [first [incr]] last
, with first
defaulting to 1, and incr
defaulting to either 1 or -1, depending on whether last
is greater than or less than first
. For other parameters, see seq(1).
you can use awk to generate your decimals eg steps of0.1
num=$(awk 'BEGIN{for(i=1;i<=10;i+=0.1)print i}')
for n in $num
do
./hw3_2_2 $n
done
or you can do it entirely in awk
awk 'BEGIN{cmd="hw3_2_2";for(i=1;i<=10;i+=0.1){c=cmd" "i;system(cmd) } }'
The easiest way is to just list them:
for a in 1.2 3.4 3.11 402.12 4.2 2342.40
do
./hw3_2_2 $a
done
If the list is huge, so you can't have it as a literal list, consider dumping it in a file and then using something like
for a in $(< my-numbers.txt)
do
./hw3_2_2 $a
done
The $(< my-numbers.txt) part is an efficient way (in Bash) to substitute the contents of the names file in that location of the script. Thanks to Dennis Williamson for pointing out that there is no need to use the external cat
command for this.
Here's another way. You can use a here doc to include your data in the script:
read -r -d '' data <<EOF
1.1
2.12
3.14159
4
5.05
EOF
for i in "$data"
do
./hw3_2_2 "$i"
done
Similarly:
array=(
1.1
2.12
3.14159
4
5.05
)
for i in "${array[@]}"
do
./hw3_2_2 "$i"
done
I usually also use "seq" as per the second answer, but just to give an answer in terms of a precision-robust integer loop and then bc conversion to a float:
#!/bin/bash
for i in {2..10..2} ; do
x=`echo "scale=2 ; ${i}/10" | bc`
echo $x
done
gives:
.2 .4 .6 .8 1.0
bash doesn't do decimal numbers. Either use something like bc
that can, or move to a more complete programming language. Beware of accuracy problems though.
精彩评论