To control the contour in bash using a string

I want to use a string to control a for loop in bash. My first test code creates what I expect and what I want:

$ aa='1 2 3 4' $ for ii in $aa; do echo $ii; done 1 2 3 4 

Instead, I would like to use something like the following. This does not produce the result that I would like (I understand why he does what he does).

 $ aa='1..4' $ for ii in $aa; do echo $ii; done 1..4 

Any suggestions on how I can modify the second example to get the same result as the first?

Thanks in advance for any thoughts. I'm slowly learning bash, but I still have a lot to learn.

Mike

+6
source share
4 answers

Designation can be written as:

 for ii in {1..4}; do echo "$ii"; done 

but {1..4} must be written like this, without any variables, and not as a result of changing variables. This is the bracketing extension in the Bash manual, and this happens before line extensions, etc. You will probably be best off using:

 for ii in $(seq 1 4); do echo "$ii"; done 

where either 1, 4, or both can be shell variables.

+2
source

You can use the seq command (see man seq ).

 $ aa='1 4' $ for ii in $(seq $aa); do echo $ii; done 
+2
source

Bash will not expand braces with variables, but you can use eval :

 $ aa='1..4' $ for ii in $(eval echo {$aa}); do echo $ii; done 1 2 3 4 

You can also split aa into an array:

 IFS=. arr=($aa) for ((ii=arr[0]; ii<arr[2]; ii++)); do echo $ii; done 

Note that IFS can only be one character, so the range .. puts numbers at indices 0 and 2.

+1
source

Note Of course, there are more elegant ways to do this, like Ben Grimm's answer, and this is not purely bash since it uses seq and awk.

One way to achieve this is by calling seq . It would be trivial if you knew the numbers in the string beforehand, so there was no need to do any conversion, since you could just do seq 1 4 or seq $a $b , for that matter.

I assume, however, that your input is indeed a string in the format you specify, i.e. 20..100 or 20..100 . To do this, you can convert the string to 2 numbers and use them as parameters for seq .

One possible way to achieve this:

 $ `echo "1..4" | sed -e 's/\.\./ /g' | awk '{print "seq", $1, $2}'` 1 2 3 4 

Note that this will work the same for any input in this format. If desired, sed can be changed to tr with similar results.

 $ x="10..15" $ `echo $x | tr "." " " | awk '{print "seq", $1, $2}'` 10 11 12 13 14 15 
0
source

Source: https://habr.com/ru/post/982401/


All Articles