Question

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?

Was it helpful?

Solution

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).

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top