When {curly braces} expansion has too many permutations

136 Views Asked by At

I know that the curly braces expansion is handled by the shell, not the command e.g. echo. When there are too many permutations, it takes too long as well as too many memory BEFORE entering the command. Is it possible to let the first permutation feed into the command, then the second permutation, and so on. It is because I have a check condition in the command, such that if certain permutation matches, it will be stopped.

echo {a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}

It can be done by many for loops in a shell script. But it would be convenient if there are certain syntax allow the same behaviour.

1

There are 1 best solutions below

1
tshiono On

Here is an idea to generate the permutations with recursion by using the given string of curly braces.

#!/bin/bash

str="{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}{a,b,c,d,}"

# function to generate permutations
perm() {
    local s1=$1
    local s2=$2
    local i
    local -a ary m

    if [[ $s1 =~ \{([^}]+)}(.*) ]]; then        # match leftmost pair of curly braces
        m=( "${BASH_REMATCH[@]}" )              # backup the capture group
        IFS=, read -ra ary <<< "${m[1]}"        # split the string on commas into array "ary"
        [[ ${m[1]} =~ ,$ ]] && ary+=( "" )      # append empty element if the string ends with comma
        for i in "${ary[@]}"; do                # loop over the array "ary"
            if [[ -n ${m[2]} ]]; then           # if other curly braces remain on the right
                perm "${m[2]}" "$s2$i"          # then recursivery call the function
            elif [[ -n $s2$i ]]; then           # end of the recursion: skip empty value which appears just once
                echo "$s2$i"
                # do your operation here with "$s2$i"
            fi
        done
    fi
}

perm "$str"

Although it instantly starts to generate the permutations, it may take a longer time to complete than the brace expansion of bash. If this is not practical in execution time, I'll update my answer with more efficient code using other languages such as perl.