[LINUX] Recursive call sample in bash function (substitute for multiple loops → in turn multiple xxx)

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

Please refer to the following (use at your own risk).

$ 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
}

#Receive depth as a parameter
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
}

#Receive depth as a parameter
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

Recommended Posts

Recursive call sample in bash function (substitute for multiple loops → in turn multiple xxx)
A simple way to avoid multiple for loops in Python
Avoid multiple loops in Python