views:

134

answers:

4

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=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?

+3  A: 

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.

unwind
Useless use of `cat`. In Bash: `$(< file)`, in `sh` (and Bash): `while read a; do ...; done < file`
Dennis Williamson
@Dennis: true, I'll correct. Thanks.
unwind
A: 

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.

Ignacio Vazquez-Abrams
+1  A: 

Here's another way. You can use a here doc to include your data in the script:

read -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
Dennis Williamson
A: 

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) } }'
ghostdog74
It's bad practice to use floating point in loops like that because if you keep adding 0.1 to 1 you will never get to 10. The counter will go from something like 9.9999999999999822 to 10.099999999999982.
Gabe
have you tried it ? pls try and then tell me if it will get to 10.
ghostdog74
If you change the `<=10` to `<10` you would expect the output to change, right? Does it?
Gabe
what do you mean expect output to change? it will stop whether you put `<` or `<=`.
ghostdog74