51

I would like to write a script that will create me an array with the following values:

{0.1 0.2 0.3 ... 2.5}

Until now I was using a script as follows:

plist=(0.1 0.2 0.3 0.4)
for i in ${plist[@]}; do
    echo "submit a simulation with this parameter:"
    echo "$i"
done

But now I need the list to be much longer ( but still with constant intervals).

Is there a way to create such an array in a single command? what is the most efficient way to create such a list?

2
  • 1
    if the interval is constant, why not make a function that takes the index and returns the value by computing it? Commented Sep 1, 2016 at 9:37
  • 2
    Tray seq command if the interval is constant. Commented Sep 1, 2016 at 9:37

4 Answers 4

77

Using seq you can say seq FIRST STEP LAST. In your case:

seq 0 0.1 2.5

Then it is a matter of storing these values in an array:

vals=($(seq 0 0.1 2.5))

You can then check the values with:

$ printf "%s\n" "${vals[@]}"
0,0
0,1
0,2
...
2,3
2,4
2,5

Yes, my locale is set to have commas instead of dots for decimals. This can be changed setting LC_NUMERIC="en_US.UTF-8".

By the way, brace expansion also allows to set an increment. The problem is that it has to be an integer:

$ echo {0..15..3}
0 3 6 9 12 15
Sign up to request clarification or add additional context in comments.

Comments

10

Bash supports C style For loops:

$ for ((i=1;i<5;i+=1)); do echo "0.${i}" ; done
0.1
0.2
0.3
0.4

2 Comments

This does not create an array, so not relevant to the question
array=($(for ((i=1;i<5;i+=1)); do echo "0.${i}"; done))
2

The most bash way to approach this is with a brace expansion. Also it is almost always better to use built-in bash functions (for compatibility and performance reasons)

ARRAY_OF_NUMBERS=({0,1}.{0..9} 2.{0..5})
echo "${ARRAY_OF_NUMBERS[@]}"

This will amount to:

0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.1 2.2 2.3 2.4 2.5

Here you can see 2 use cases of the brace expansion. One with no increment {0,1} and then the increment of one in the expansion of {0..9} and {1..5}. Since bash does not support built-in floating point numbers pretty much everything must be handled as an integer or a string. That said the sequence of 2"."{1..5} expands to "2.0 2.1 2.2 2.3 2.4 2.5". Because in this case the "2" and the "." are handled as a normal string, before entering the brace expansion, since the terminator of array elements in bash is the whitespace.

This approach might seem archaic on the first glance, but as is bash in a way. The benefits are it is easily scalable, does not depend on other commands nor processes and has maximum compatibilty with other bash environments, where seq might not be available.

See this article for explanation seq vs brace expansion.

Avoid the 'seq' command in Bash?

Hope I could help anyone who stumbles upon this after me!

Comments

1

Complementing the main answer

In my case, seq was not the best choice.
To produce a sequence, you can also use the jot utility. However, this command has a more elaborated syntaxis.

# 1 2 3 4
jot - 1 4

# 3 evenly distributed numbers between 0 and 10
# 0 5 10
jot 3 0 10

# a b c ... z
jot -c - 97 122

1 Comment

Could you elaborate on why jot is better than seq in some cases?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.