# Introduction

Due to various circumstances, I have to write dynamic multiple loop processing (~~ ← I don't know what you are saying ~~) in bash.

``````\$ ./xxx.sh 5
``````

What if I do it, I will carry out multiple loops 5 times. It is a requirement.

** Can't you do that with bash ** I thought, but I was able to realize it easily. So share.

# Main story

## specification

** Calculates and outputs all combinations of numerical values for the specified number of digits. ** ** In particular

``````\$ ./xxx.sh 3
``````

If, 3 digits 000 to 999, a total of 1000 numbers will be output to the console [^ 1].

[^ 1]: As you commented, this specification can be easily realized with the ` seq` command, but it is just an example of recursive call.

## code

``````\$ cat recursive_loop.sh
#!/bin/bash

SOURCE_CHARS="0123456789"
LENGTH=\${#SOURCE_CHARS}

#Result string and maximum depth (initial value is 1)
result_str=""
depth_max=1

#Recursive function body
function loop_func () {
#Explicitly use local variables
local _count=\${1}
local _i=0
local _before=""

for ((_i=0; _i<\${LENGTH}; _i++))
do
#Concatenate one character at the end
_before=\${result_str}
result_str=\${result_str}\${SOURCE_CHARS:\${_i}:1}

#Result output when the depth is maximized
# _count starts at 0, so depth_subtracting 1 from max
if [ \${_count} -ge \$((\${depth_max}-1)) ]; then
echo \${result_str}
#Recursive call if not maximum
else
loop_func \$((\${_count}+1))
fi

# if/else In either case, the character string is returned before concatenation.
result_str=\${_before}
done
}

if [ \${#} -ge 1 ]; then
if [ \${1} -ge 1 ]; then
depth_max=\${1}
fi
fi

#Start recursive call
loop_func 0
``````

## Execution result

``````\$ ./recursive_loop.sh
0
(Omitted)
9
\$ ./recursive_loop.sh 2
00
(Omitted)
99
\$ ./recursive_loop.sh 3
000
(Omitted)
999
\$ ./recursive_test.sh 3 | wc -l
1000
``````

## Generalization

If it is a loop to multiplex, it will be confusing, so if you want to use "multiplex xxx" for general purposes, use the following.

``````\$ cat recursive_xxx.sh
#!/bin/bash

#Maximum depth (initial value is 1)
depth_max=1

#Recursive function body
#Processing according to xxx is provisionally set to echo
function xxx_func () {
#Explicitly use local variables
local _count=\${1}

#Finish when the depth is maximized
# _count starts at 0, so depth_subtracting 1 from max
if [ \${_count} -ge \$((\${depth_max}-1)) ]; then
echo "[\${_count}] FINISH (Depth=\${depth_max})"
#Recursive call if not maximum
else
echo "[\${_count}] --->"
xxx_func \$((\${_count}+1))
echo "[\${_count}] <---"
fi
}

if [ \${#} -ge 1 ]; then
if [ \${1} -ge 1 ]; then
depth_max=\${1}
fi
fi

#Start recursive call
xxx_func 0

user@user-VirtualBox:~/zip\$ ./recursive_xxx.sh 3
[0] --->
[1] --->
[2] FINISH (Depth=3)
[1] <---
[0] <---
``````

## Technology? point

--Can write functions --Local variables can be used in the function

Recursive calls were also possible to meet these requirements in terms of language specifications.

~~ Algorithmically, my head seemed to be confused, but I managed to do it ~~

# in conclusion

## Impressions

You can do it with bash! Lol

## Confirmation environment

• Ubuntu 18.04 LTS

Recommended Posts