Force alphabetical order in for loop with if conditions

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

up vote
2
down vote

favorite

I want to create a large number of folders and do some operations in them. The folder names are based on permutations of several chemical elements which I define as variables in a for loop:

for Element in Cr Hf Mo Nb Ta Ti V W Zr

I want a folder for all permutations of 4 of the elements in alphabetical order, so that I get subfolders containing the letters CrHfMoNb, CrHfMoTa, … and so on. I tried to do this with 4 nestled for loops, but for simplicity I will demonstrate it here with just 2. The code I have come up with is:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    for Elemen in Hf Mo Nb Ta Ti V W Zr; do
        mkdir "$Element""$Elemen"N     # the N at the end is intended
    done
done

This yields the folders I want but a lot of unnecessary ones too, because I also get combinations like TiNbN or ZrVN which are not alphabetic and also duplicates like HfHfN. I can get rid of the duplicates by adding an if statement to the third line

do [ "$Element" != "$Elemen" ] && mkdir "$Element""$Elemen"N

although these duplicate folders do not disappear completely but become “phantom” files in my directory, meaning that they are called HfHfN etc. but have no file extension. The real problem however is the rest of the folders. I tried adding more if statements like

do [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] && mkdir "$Element""$Elemen"N

to decrease the allowed number of permutations but this does not get rid of anything. I also tried separating the if statements into their own respective for loops but that does not change anything aswell:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] &&
    for Elemen in Hf Mo Nb Ta Ti V W Zr;  do...

I’m not entirely sure if > is the right if command, but from this list http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html it seems the most reasonable one. Using commands like -ne, -lt, -le, -gt does not work as well, because they demand an integer, so the letters are not accepted. In the end I want to combine 4 loops together so it becomes a bit difficult to see through. What am I missing?

share|improve this question

  • 4

    Does it have to be a shell script? Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.
    – n.st
    Nov 29 at 14:11

  • +1 for reducing the question to a smaller but equivalent problem space.
    – studog
    Nov 29 at 19:47

  • 1

    All of the presented solutions work! I accepted the fastest answer. Thank you very much!
    – Andreas
    Nov 30 at 8:20

up vote
2
down vote

favorite

I want to create a large number of folders and do some operations in them. The folder names are based on permutations of several chemical elements which I define as variables in a for loop:

for Element in Cr Hf Mo Nb Ta Ti V W Zr

I want a folder for all permutations of 4 of the elements in alphabetical order, so that I get subfolders containing the letters CrHfMoNb, CrHfMoTa, … and so on. I tried to do this with 4 nestled for loops, but for simplicity I will demonstrate it here with just 2. The code I have come up with is:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    for Elemen in Hf Mo Nb Ta Ti V W Zr; do
        mkdir "$Element""$Elemen"N     # the N at the end is intended
    done
done

This yields the folders I want but a lot of unnecessary ones too, because I also get combinations like TiNbN or ZrVN which are not alphabetic and also duplicates like HfHfN. I can get rid of the duplicates by adding an if statement to the third line

do [ "$Element" != "$Elemen" ] && mkdir "$Element""$Elemen"N

although these duplicate folders do not disappear completely but become “phantom” files in my directory, meaning that they are called HfHfN etc. but have no file extension. The real problem however is the rest of the folders. I tried adding more if statements like

do [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] && mkdir "$Element""$Elemen"N

to decrease the allowed number of permutations but this does not get rid of anything. I also tried separating the if statements into their own respective for loops but that does not change anything aswell:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] &&
    for Elemen in Hf Mo Nb Ta Ti V W Zr;  do...

I’m not entirely sure if > is the right if command, but from this list http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html it seems the most reasonable one. Using commands like -ne, -lt, -le, -gt does not work as well, because they demand an integer, so the letters are not accepted. In the end I want to combine 4 loops together so it becomes a bit difficult to see through. What am I missing?

share|improve this question

  • 4

    Does it have to be a shell script? Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.
    – n.st
    Nov 29 at 14:11

  • +1 for reducing the question to a smaller but equivalent problem space.
    – studog
    Nov 29 at 19:47

  • 1

    All of the presented solutions work! I accepted the fastest answer. Thank you very much!
    – Andreas
    Nov 30 at 8:20

up vote
2
down vote

favorite

up vote
2
down vote

favorite

I want to create a large number of folders and do some operations in them. The folder names are based on permutations of several chemical elements which I define as variables in a for loop:

for Element in Cr Hf Mo Nb Ta Ti V W Zr

I want a folder for all permutations of 4 of the elements in alphabetical order, so that I get subfolders containing the letters CrHfMoNb, CrHfMoTa, … and so on. I tried to do this with 4 nestled for loops, but for simplicity I will demonstrate it here with just 2. The code I have come up with is:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    for Elemen in Hf Mo Nb Ta Ti V W Zr; do
        mkdir "$Element""$Elemen"N     # the N at the end is intended
    done
done

This yields the folders I want but a lot of unnecessary ones too, because I also get combinations like TiNbN or ZrVN which are not alphabetic and also duplicates like HfHfN. I can get rid of the duplicates by adding an if statement to the third line

do [ "$Element" != "$Elemen" ] && mkdir "$Element""$Elemen"N

although these duplicate folders do not disappear completely but become “phantom” files in my directory, meaning that they are called HfHfN etc. but have no file extension. The real problem however is the rest of the folders. I tried adding more if statements like

do [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] && mkdir "$Element""$Elemen"N

to decrease the allowed number of permutations but this does not get rid of anything. I also tried separating the if statements into their own respective for loops but that does not change anything aswell:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] &&
    for Elemen in Hf Mo Nb Ta Ti V W Zr;  do...

I’m not entirely sure if > is the right if command, but from this list http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html it seems the most reasonable one. Using commands like -ne, -lt, -le, -gt does not work as well, because they demand an integer, so the letters are not accepted. In the end I want to combine 4 loops together so it becomes a bit difficult to see through. What am I missing?

share|improve this question

I want to create a large number of folders and do some operations in them. The folder names are based on permutations of several chemical elements which I define as variables in a for loop:

for Element in Cr Hf Mo Nb Ta Ti V W Zr

I want a folder for all permutations of 4 of the elements in alphabetical order, so that I get subfolders containing the letters CrHfMoNb, CrHfMoTa, … and so on. I tried to do this with 4 nestled for loops, but for simplicity I will demonstrate it here with just 2. The code I have come up with is:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    for Elemen in Hf Mo Nb Ta Ti V W Zr; do
        mkdir "$Element""$Elemen"N     # the N at the end is intended
    done
done

This yields the folders I want but a lot of unnecessary ones too, because I also get combinations like TiNbN or ZrVN which are not alphabetic and also duplicates like HfHfN. I can get rid of the duplicates by adding an if statement to the third line

do [ "$Element" != "$Elemen" ] && mkdir "$Element""$Elemen"N

although these duplicate folders do not disappear completely but become “phantom” files in my directory, meaning that they are called HfHfN etc. but have no file extension. The real problem however is the rest of the folders. I tried adding more if statements like

do [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] && mkdir "$Element""$Elemen"N

to decrease the allowed number of permutations but this does not get rid of anything. I also tried separating the if statements into their own respective for loops but that does not change anything aswell:

for Element in Cr Hf Mo Nb Ta Ti V W Zr; do
    [ "$Element" != "$Elemen" ] && [ "$Element" > "$Elemen" ] &&
    for Elemen in Hf Mo Nb Ta Ti V W Zr;  do...

I’m not entirely sure if > is the right if command, but from this list http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html it seems the most reasonable one. Using commands like -ne, -lt, -le, -gt does not work as well, because they demand an integer, so the letters are not accepted. In the end I want to combine 4 loops together so it becomes a bit difficult to see through. What am I missing?

bash for

share|improve this question

share|improve this question

share|improve this question

share|improve this question

edited Nov 29 at 17:59

Kusalananda

119k16223364

119k16223364

asked Nov 29 at 14:04

Andreas

253

253

  • 4

    Does it have to be a shell script? Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.
    – n.st
    Nov 29 at 14:11

  • +1 for reducing the question to a smaller but equivalent problem space.
    – studog
    Nov 29 at 19:47

  • 1

    All of the presented solutions work! I accepted the fastest answer. Thank you very much!
    – Andreas
    Nov 30 at 8:20

  • 4

    Does it have to be a shell script? Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.
    – n.st
    Nov 29 at 14:11

  • +1 for reducing the question to a smaller but equivalent problem space.
    – studog
    Nov 29 at 19:47

  • 1

    All of the presented solutions work! I accepted the fastest answer. Thank you very much!
    – Andreas
    Nov 30 at 8:20

4

4

Does it have to be a shell script? Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.
– n.st
Nov 29 at 14:11

Does it have to be a shell script? Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.
– n.st
Nov 29 at 14:11

+1 for reducing the question to a smaller but equivalent problem space.
– studog
Nov 29 at 19:47

+1 for reducing the question to a smaller but equivalent problem space.
– studog
Nov 29 at 19:47

1

1

All of the presented solutions work! I accepted the fastest answer. Thank you very much!
– Andreas
Nov 30 at 8:20

All of the presented solutions work! I accepted the fastest answer. Thank you very much!
– Andreas
Nov 30 at 8:20

4 Answers
4

active

oldest

votes

up vote
1
down vote

accepted

Spend a couple steps on skipping redundancies. It’ll speed up the process overall.

declare -a lst=( Cr Hf Mo Nb Ta Ti V W Zr ) # make an array
for a in ${lst[@]}                          # for each element
do  for b in ${lst[@]:1}                    # for each but the 1st
    do [[ "$b" > "$a" ]] || continue        # keep them alphabetical and skip wasted work
        for c in ${lst[@]:2}                # for each but the first 2
        do  [[ "$c" > "$b" ]] || continue   # keep them alphabetical and skip wasted work
            for d in ${lst[@]:3}            # for each but the first 3
            do [[ "$d" > "$c" ]] || continue # keep them alphabetical and skip wasted work
                mkdir "$a$b$c$d" && echo "Made: $a$b$c$d" || echo "Fail: $a$b$c$d"
            done
        done
    done
done

The redundancy skips are for when later loops are starting, such as when the outer loop is on element 4 but the second loop is still on 3 or 4. These skip those, because they wouldn’t be alphabetic combinations. Doing that also guarantees no repeats. This generated 126 distinct dirs with no errors in 0m8.126s in git bash on my laptop with no subshells other than mkdir.

share|improve this answer

    up vote
    6
    down vote

    #/bin/sh
    
    # shellcheck disable=SC2046
    # ^ word-splitting by the shell is intentional in this file
    
    elems="Cr Hf Mo Nb Ta Ti V W Zr"
    for a in $elems
    do
        for b in $elems
        do
            for c in $elems
            do
                for d in $elems
                do
                    # for a set of any four elements:
                    #   string them together, separated by NUL-bytes
                    #   sort them lexicographically ...
                    #     ... with NUL separating the elements (-z)
                    #     ... and eliminate duplicates (-u)
                    #   then replace the NUL bytes with line breaks
                    #   allow the shell to split on those line breaks
                    #   and chuck the resulting chunks into $1, $2, etc
                    set -- $(printf '%s' "$a" "$b" "$c" "$d" | sort -z -u | tr "" "n")
    
                    # only if the current selection of elements consisted of four
                    # different ones (remember we eliminated duplicates):
                    if [ $# -eq 4 ]
                    then
                        # create a directory, don't error out if it already exists (-p)
                        mkdir -p "$(printf '%s' "$@")"
                    fi
                done
            done
        done
    done
    

    Not very efficient (sort calls even for obvious non-candidates and multiple mkdir calls for the same directory name), but at a maximum of 94 = 6561 iterations of the inner loop and with it being a single-use script, I don’t think this is worth spending much time on optimisation.


    Edit:
    Benchmark on a Xeon E3-1231v3 without mkdir:

    ./elemdirs.sh > /dev/null  11.66s user 1.73s system 173% cpu 7.725 total
    

    and with it:

    ./elemdirs.sh > /dev/null  13.80s user 2.16s system 156% cpu 10.215 total
    

    It produces 126 directories, the expected number of combinations with k = 4, n = 9.

    share|improve this answer

      up vote
      6
      down vote

      Using Perl and the Algorithm::Combinatorics module:

      perl -MAlgorithm::Combinatorics=combinations -e '$"=""; map { mkdir "@{$_}N" } combinations([qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4)'
      

      This would create the 126 directories that you get from all combinations of four of the included words. Each directory’s name will have a N at the end. The individual words will always occur in alphabetical order in the directory names due to the initial ordering of the array in the code.

      As a proper Perl script:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      use English;
      use Algorithm::Combinatorics qw(combinations);
      
      # When interpolating a list in a string (@{$ARG} below), don't use a delimiter
      local $LIST_SEPARATOR = "";
      
      # Get all combinations, and create a directory for each combination
      map { mkdir "@{$ARG}N" } combinations( [qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4 );
      

      This would run pretty much instantaneously and is easily extended to include further words or length of combinations.

      You would probably be able do something pretty similar in Python…


      A recursive shell implementation (just for fun, recursive shell functions are seldom very efficient):

      #!/bin/sh
      
      build_combinations () {
          set_size=$1
          shift
      
          if [ "$set_size" -eq 0 ]; then
              printf 'N'
          else
              for token do
                  shift
                  for reminder in $(build_combinations "$(( set_size - 1 ))" "$@")
                  do
                      printf '%s%sn' "$token" "$reminder"
                  done
              done
          fi
      }
      
      build_combinations 4 Cr Hf Mo Nb Ta Ti V W Zr | xargs mkdir
      

      Idea from having read studog’s answer and inspiration from various bits of an answer to a StackOverflow question.

      Note that the saving grace of this solution is that the directory names always end with a N. The recursive stop branch outputs N rather than an empty string, which makes the whole thing work. Without it (printing an empty string or a newline), the loop with the command substitution would have nothing to loop over and there would be no output (due to the default value of the IFS variable).

      share|improve this answer

        up vote
        2
        down vote

        An improvement on @n.st’s answer that takes advantage of the fact the elements are in sorted order to start with. It’s also a little clearer in my opinion.

        #!/bin/bash
        
        elements=(Cr Hf Mo Nb Ta Ti V W Zr)
        len=${#elements[@]}
        
        (( a_end = len - 3 ))
        (( b_end = len - 2 ))
        (( c_end = len - 1 ))
        (( d_end = len - 0 ))
        
        (( a = 0 ))
        while (( a < a_end )); do
           (( b = a + 1 ))
           while (( b < b_end )); do
              (( c = b + 1 ))
              while (( c < c_end )); do
                 (( d = c + 1 ))
                 while (( d < d_end )); do
                    mkdir "${elements[$a]}${elements[$b]}${elements[$c]}${elements[$d]}"
                    (( d++ ))
                 done
                 (( c++ ))
              done
              (( b++ ))
           done
           (( a++ ))
        done
        

        The key part every inner loop starts at the next element index from the enclosing loop. This is a pretty common pattern for generating all combinations of a list of items.

        Runtime:

        user@host:~/so$ time ./do.sh 
        
        real    0m0.140s
        user    0m0.085s
        sys 0m0.044s
        

        with

        user@host:~/so$ ls -1d Cr* Hf* Mo* Nb* Ta* Ti* V* W* Zr* | wc -l
        ls: cannot access 'V*': No such file or directory
        ls: cannot access 'W*': No such file or directory
        ls: cannot access 'Zr*': No such file or directory
        126
        

        share|improve this answer

        • 1

          It looks like this would also lend itself to a recursive implementation, which would make it possible to adjust the number of components of the directory names etc. easier. I haven’t seriously thought about it though.
          – Kusalananda
          Nov 29 at 21:04

        • In fact it does lend itself to a recursive implementation! I thought about doing that briefly but decided that the “unrolled” version was more instructive for this particular question.
          – studog
          Nov 29 at 22:13

        • Well, I made one.
          – Kusalananda
          Nov 29 at 22:21

        Your Answer

        StackExchange.ready(function() {
        var channelOptions = {
        tags: “”.split(” “),
        id: “106”
        };
        initTagRenderer(“”.split(” “), “”.split(” “), channelOptions);

        StackExchange.using(“externalEditor”, function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using(“snippets”, function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: ‘answer’,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: “”,
        imageUploader: {
        brandingHtml: “Powered by u003ca class=”icon-imgur-white” href=”https://imgur.com/”u003eu003c/au003e”,
        contentPolicyHtml: “User contributions licensed under u003ca href=”https://creativecommons.org/licenses/by-sa/3.0/”u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href=”https://stackoverflow.com/legal/content-policy”u003e(content policy)u003c/au003e”,
        allowUrls: true
        },
        onDemand: true,
        discardSelector: “.discard-answer”
        ,immediatelyShowMarkdownHelp:true
        });

        }
        });

        draft saved
        draft discarded

        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2funix.stackexchange.com%2fquestions%2f484924%2fforce-alphabetical-order-in-for-loop-with-if-conditions%23new-answer’, ‘question_page’);
        }
        );

        Post as a guest

        Required, but never shown

        4 Answers
        4

        active

        oldest

        votes

        4 Answers
        4

        active

        oldest

        votes

        active

        oldest

        votes

        active

        oldest

        votes

        up vote
        1
        down vote

        accepted

        Spend a couple steps on skipping redundancies. It’ll speed up the process overall.

        declare -a lst=( Cr Hf Mo Nb Ta Ti V W Zr ) # make an array
        for a in ${lst[@]}                          # for each element
        do  for b in ${lst[@]:1}                    # for each but the 1st
            do [[ "$b" > "$a" ]] || continue        # keep them alphabetical and skip wasted work
                for c in ${lst[@]:2}                # for each but the first 2
                do  [[ "$c" > "$b" ]] || continue   # keep them alphabetical and skip wasted work
                    for d in ${lst[@]:3}            # for each but the first 3
                    do [[ "$d" > "$c" ]] || continue # keep them alphabetical and skip wasted work
                        mkdir "$a$b$c$d" && echo "Made: $a$b$c$d" || echo "Fail: $a$b$c$d"
                    done
                done
            done
        done
        

        The redundancy skips are for when later loops are starting, such as when the outer loop is on element 4 but the second loop is still on 3 or 4. These skip those, because they wouldn’t be alphabetic combinations. Doing that also guarantees no repeats. This generated 126 distinct dirs with no errors in 0m8.126s in git bash on my laptop with no subshells other than mkdir.

        share|improve this answer

          up vote
          1
          down vote

          accepted

          Spend a couple steps on skipping redundancies. It’ll speed up the process overall.

          declare -a lst=( Cr Hf Mo Nb Ta Ti V W Zr ) # make an array
          for a in ${lst[@]}                          # for each element
          do  for b in ${lst[@]:1}                    # for each but the 1st
              do [[ "$b" > "$a" ]] || continue        # keep them alphabetical and skip wasted work
                  for c in ${lst[@]:2}                # for each but the first 2
                  do  [[ "$c" > "$b" ]] || continue   # keep them alphabetical and skip wasted work
                      for d in ${lst[@]:3}            # for each but the first 3
                      do [[ "$d" > "$c" ]] || continue # keep them alphabetical and skip wasted work
                          mkdir "$a$b$c$d" && echo "Made: $a$b$c$d" || echo "Fail: $a$b$c$d"
                      done
                  done
              done
          done
          

          The redundancy skips are for when later loops are starting, such as when the outer loop is on element 4 but the second loop is still on 3 or 4. These skip those, because they wouldn’t be alphabetic combinations. Doing that also guarantees no repeats. This generated 126 distinct dirs with no errors in 0m8.126s in git bash on my laptop with no subshells other than mkdir.

          share|improve this answer

            up vote
            1
            down vote

            accepted

            up vote
            1
            down vote

            accepted

            Spend a couple steps on skipping redundancies. It’ll speed up the process overall.

            declare -a lst=( Cr Hf Mo Nb Ta Ti V W Zr ) # make an array
            for a in ${lst[@]}                          # for each element
            do  for b in ${lst[@]:1}                    # for each but the 1st
                do [[ "$b" > "$a" ]] || continue        # keep them alphabetical and skip wasted work
                    for c in ${lst[@]:2}                # for each but the first 2
                    do  [[ "$c" > "$b" ]] || continue   # keep them alphabetical and skip wasted work
                        for d in ${lst[@]:3}            # for each but the first 3
                        do [[ "$d" > "$c" ]] || continue # keep them alphabetical and skip wasted work
                            mkdir "$a$b$c$d" && echo "Made: $a$b$c$d" || echo "Fail: $a$b$c$d"
                        done
                    done
                done
            done
            

            The redundancy skips are for when later loops are starting, such as when the outer loop is on element 4 but the second loop is still on 3 or 4. These skip those, because they wouldn’t be alphabetic combinations. Doing that also guarantees no repeats. This generated 126 distinct dirs with no errors in 0m8.126s in git bash on my laptop with no subshells other than mkdir.

            share|improve this answer

            Spend a couple steps on skipping redundancies. It’ll speed up the process overall.

            declare -a lst=( Cr Hf Mo Nb Ta Ti V W Zr ) # make an array
            for a in ${lst[@]}                          # for each element
            do  for b in ${lst[@]:1}                    # for each but the 1st
                do [[ "$b" > "$a" ]] || continue        # keep them alphabetical and skip wasted work
                    for c in ${lst[@]:2}                # for each but the first 2
                    do  [[ "$c" > "$b" ]] || continue   # keep them alphabetical and skip wasted work
                        for d in ${lst[@]:3}            # for each but the first 3
                        do [[ "$d" > "$c" ]] || continue # keep them alphabetical and skip wasted work
                            mkdir "$a$b$c$d" && echo "Made: $a$b$c$d" || echo "Fail: $a$b$c$d"
                        done
                    done
                done
            done
            

            The redundancy skips are for when later loops are starting, such as when the outer loop is on element 4 but the second loop is still on 3 or 4. These skip those, because they wouldn’t be alphabetic combinations. Doing that also guarantees no repeats. This generated 126 distinct dirs with no errors in 0m8.126s in git bash on my laptop with no subshells other than mkdir.

            share|improve this answer

            share|improve this answer

            share|improve this answer

            answered Nov 29 at 15:22

            Paul Hodges

            1663

            1663

                up vote
                6
                down vote

                #/bin/sh
                
                # shellcheck disable=SC2046
                # ^ word-splitting by the shell is intentional in this file
                
                elems="Cr Hf Mo Nb Ta Ti V W Zr"
                for a in $elems
                do
                    for b in $elems
                    do
                        for c in $elems
                        do
                            for d in $elems
                            do
                                # for a set of any four elements:
                                #   string them together, separated by NUL-bytes
                                #   sort them lexicographically ...
                                #     ... with NUL separating the elements (-z)
                                #     ... and eliminate duplicates (-u)
                                #   then replace the NUL bytes with line breaks
                                #   allow the shell to split on those line breaks
                                #   and chuck the resulting chunks into $1, $2, etc
                                set -- $(printf '%s' "$a" "$b" "$c" "$d" | sort -z -u | tr "" "n")
                
                                # only if the current selection of elements consisted of four
                                # different ones (remember we eliminated duplicates):
                                if [ $# -eq 4 ]
                                then
                                    # create a directory, don't error out if it already exists (-p)
                                    mkdir -p "$(printf '%s' "$@")"
                                fi
                            done
                        done
                    done
                done
                

                Not very efficient (sort calls even for obvious non-candidates and multiple mkdir calls for the same directory name), but at a maximum of 94 = 6561 iterations of the inner loop and with it being a single-use script, I don’t think this is worth spending much time on optimisation.


                Edit:
                Benchmark on a Xeon E3-1231v3 without mkdir:

                ./elemdirs.sh > /dev/null  11.66s user 1.73s system 173% cpu 7.725 total
                

                and with it:

                ./elemdirs.sh > /dev/null  13.80s user 2.16s system 156% cpu 10.215 total
                

                It produces 126 directories, the expected number of combinations with k = 4, n = 9.

                share|improve this answer

                  up vote
                  6
                  down vote

                  #/bin/sh
                  
                  # shellcheck disable=SC2046
                  # ^ word-splitting by the shell is intentional in this file
                  
                  elems="Cr Hf Mo Nb Ta Ti V W Zr"
                  for a in $elems
                  do
                      for b in $elems
                      do
                          for c in $elems
                          do
                              for d in $elems
                              do
                                  # for a set of any four elements:
                                  #   string them together, separated by NUL-bytes
                                  #   sort them lexicographically ...
                                  #     ... with NUL separating the elements (-z)
                                  #     ... and eliminate duplicates (-u)
                                  #   then replace the NUL bytes with line breaks
                                  #   allow the shell to split on those line breaks
                                  #   and chuck the resulting chunks into $1, $2, etc
                                  set -- $(printf '%s' "$a" "$b" "$c" "$d" | sort -z -u | tr "" "n")
                  
                                  # only if the current selection of elements consisted of four
                                  # different ones (remember we eliminated duplicates):
                                  if [ $# -eq 4 ]
                                  then
                                      # create a directory, don't error out if it already exists (-p)
                                      mkdir -p "$(printf '%s' "$@")"
                                  fi
                              done
                          done
                      done
                  done
                  

                  Not very efficient (sort calls even for obvious non-candidates and multiple mkdir calls for the same directory name), but at a maximum of 94 = 6561 iterations of the inner loop and with it being a single-use script, I don’t think this is worth spending much time on optimisation.


                  Edit:
                  Benchmark on a Xeon E3-1231v3 without mkdir:

                  ./elemdirs.sh > /dev/null  11.66s user 1.73s system 173% cpu 7.725 total
                  

                  and with it:

                  ./elemdirs.sh > /dev/null  13.80s user 2.16s system 156% cpu 10.215 total
                  

                  It produces 126 directories, the expected number of combinations with k = 4, n = 9.

                  share|improve this answer

                    up vote
                    6
                    down vote

                    up vote
                    6
                    down vote

                    #/bin/sh
                    
                    # shellcheck disable=SC2046
                    # ^ word-splitting by the shell is intentional in this file
                    
                    elems="Cr Hf Mo Nb Ta Ti V W Zr"
                    for a in $elems
                    do
                        for b in $elems
                        do
                            for c in $elems
                            do
                                for d in $elems
                                do
                                    # for a set of any four elements:
                                    #   string them together, separated by NUL-bytes
                                    #   sort them lexicographically ...
                                    #     ... with NUL separating the elements (-z)
                                    #     ... and eliminate duplicates (-u)
                                    #   then replace the NUL bytes with line breaks
                                    #   allow the shell to split on those line breaks
                                    #   and chuck the resulting chunks into $1, $2, etc
                                    set -- $(printf '%s' "$a" "$b" "$c" "$d" | sort -z -u | tr "" "n")
                    
                                    # only if the current selection of elements consisted of four
                                    # different ones (remember we eliminated duplicates):
                                    if [ $# -eq 4 ]
                                    then
                                        # create a directory, don't error out if it already exists (-p)
                                        mkdir -p "$(printf '%s' "$@")"
                                    fi
                                done
                            done
                        done
                    done
                    

                    Not very efficient (sort calls even for obvious non-candidates and multiple mkdir calls for the same directory name), but at a maximum of 94 = 6561 iterations of the inner loop and with it being a single-use script, I don’t think this is worth spending much time on optimisation.


                    Edit:
                    Benchmark on a Xeon E3-1231v3 without mkdir:

                    ./elemdirs.sh > /dev/null  11.66s user 1.73s system 173% cpu 7.725 total
                    

                    and with it:

                    ./elemdirs.sh > /dev/null  13.80s user 2.16s system 156% cpu 10.215 total
                    

                    It produces 126 directories, the expected number of combinations with k = 4, n = 9.

                    share|improve this answer

                    #/bin/sh
                    
                    # shellcheck disable=SC2046
                    # ^ word-splitting by the shell is intentional in this file
                    
                    elems="Cr Hf Mo Nb Ta Ti V W Zr"
                    for a in $elems
                    do
                        for b in $elems
                        do
                            for c in $elems
                            do
                                for d in $elems
                                do
                                    # for a set of any four elements:
                                    #   string them together, separated by NUL-bytes
                                    #   sort them lexicographically ...
                                    #     ... with NUL separating the elements (-z)
                                    #     ... and eliminate duplicates (-u)
                                    #   then replace the NUL bytes with line breaks
                                    #   allow the shell to split on those line breaks
                                    #   and chuck the resulting chunks into $1, $2, etc
                                    set -- $(printf '%s' "$a" "$b" "$c" "$d" | sort -z -u | tr "" "n")
                    
                                    # only if the current selection of elements consisted of four
                                    # different ones (remember we eliminated duplicates):
                                    if [ $# -eq 4 ]
                                    then
                                        # create a directory, don't error out if it already exists (-p)
                                        mkdir -p "$(printf '%s' "$@")"
                                    fi
                                done
                            done
                        done
                    done
                    

                    Not very efficient (sort calls even for obvious non-candidates and multiple mkdir calls for the same directory name), but at a maximum of 94 = 6561 iterations of the inner loop and with it being a single-use script, I don’t think this is worth spending much time on optimisation.


                    Edit:
                    Benchmark on a Xeon E3-1231v3 without mkdir:

                    ./elemdirs.sh > /dev/null  11.66s user 1.73s system 173% cpu 7.725 total
                    

                    and with it:

                    ./elemdirs.sh > /dev/null  13.80s user 2.16s system 156% cpu 10.215 total
                    

                    It produces 126 directories, the expected number of combinations with k = 4, n = 9.

                    share|improve this answer

                    share|improve this answer

                    share|improve this answer

                    edited Nov 29 at 14:38

                    answered Nov 29 at 14:28

                    n.st

                    5,17111843

                    5,17111843

                        up vote
                        6
                        down vote

                        Using Perl and the Algorithm::Combinatorics module:

                        perl -MAlgorithm::Combinatorics=combinations -e '$"=""; map { mkdir "@{$_}N" } combinations([qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4)'
                        

                        This would create the 126 directories that you get from all combinations of four of the included words. Each directory’s name will have a N at the end. The individual words will always occur in alphabetical order in the directory names due to the initial ordering of the array in the code.

                        As a proper Perl script:

                        #!/usr/bin/perl
                        
                        use strict;
                        use warnings;
                        
                        use English;
                        use Algorithm::Combinatorics qw(combinations);
                        
                        # When interpolating a list in a string (@{$ARG} below), don't use a delimiter
                        local $LIST_SEPARATOR = "";
                        
                        # Get all combinations, and create a directory for each combination
                        map { mkdir "@{$ARG}N" } combinations( [qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4 );
                        

                        This would run pretty much instantaneously and is easily extended to include further words or length of combinations.

                        You would probably be able do something pretty similar in Python…


                        A recursive shell implementation (just for fun, recursive shell functions are seldom very efficient):

                        #!/bin/sh
                        
                        build_combinations () {
                            set_size=$1
                            shift
                        
                            if [ "$set_size" -eq 0 ]; then
                                printf 'N'
                            else
                                for token do
                                    shift
                                    for reminder in $(build_combinations "$(( set_size - 1 ))" "$@")
                                    do
                                        printf '%s%sn' "$token" "$reminder"
                                    done
                                done
                            fi
                        }
                        
                        build_combinations 4 Cr Hf Mo Nb Ta Ti V W Zr | xargs mkdir
                        

                        Idea from having read studog’s answer and inspiration from various bits of an answer to a StackOverflow question.

                        Note that the saving grace of this solution is that the directory names always end with a N. The recursive stop branch outputs N rather than an empty string, which makes the whole thing work. Without it (printing an empty string or a newline), the loop with the command substitution would have nothing to loop over and there would be no output (due to the default value of the IFS variable).

                        share|improve this answer

                          up vote
                          6
                          down vote

                          Using Perl and the Algorithm::Combinatorics module:

                          perl -MAlgorithm::Combinatorics=combinations -e '$"=""; map { mkdir "@{$_}N" } combinations([qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4)'
                          

                          This would create the 126 directories that you get from all combinations of four of the included words. Each directory’s name will have a N at the end. The individual words will always occur in alphabetical order in the directory names due to the initial ordering of the array in the code.

                          As a proper Perl script:

                          #!/usr/bin/perl
                          
                          use strict;
                          use warnings;
                          
                          use English;
                          use Algorithm::Combinatorics qw(combinations);
                          
                          # When interpolating a list in a string (@{$ARG} below), don't use a delimiter
                          local $LIST_SEPARATOR = "";
                          
                          # Get all combinations, and create a directory for each combination
                          map { mkdir "@{$ARG}N" } combinations( [qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4 );
                          

                          This would run pretty much instantaneously and is easily extended to include further words or length of combinations.

                          You would probably be able do something pretty similar in Python…


                          A recursive shell implementation (just for fun, recursive shell functions are seldom very efficient):

                          #!/bin/sh
                          
                          build_combinations () {
                              set_size=$1
                              shift
                          
                              if [ "$set_size" -eq 0 ]; then
                                  printf 'N'
                              else
                                  for token do
                                      shift
                                      for reminder in $(build_combinations "$(( set_size - 1 ))" "$@")
                                      do
                                          printf '%s%sn' "$token" "$reminder"
                                      done
                                  done
                              fi
                          }
                          
                          build_combinations 4 Cr Hf Mo Nb Ta Ti V W Zr | xargs mkdir
                          

                          Idea from having read studog’s answer and inspiration from various bits of an answer to a StackOverflow question.

                          Note that the saving grace of this solution is that the directory names always end with a N. The recursive stop branch outputs N rather than an empty string, which makes the whole thing work. Without it (printing an empty string or a newline), the loop with the command substitution would have nothing to loop over and there would be no output (due to the default value of the IFS variable).

                          share|improve this answer

                            up vote
                            6
                            down vote

                            up vote
                            6
                            down vote

                            Using Perl and the Algorithm::Combinatorics module:

                            perl -MAlgorithm::Combinatorics=combinations -e '$"=""; map { mkdir "@{$_}N" } combinations([qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4)'
                            

                            This would create the 126 directories that you get from all combinations of four of the included words. Each directory’s name will have a N at the end. The individual words will always occur in alphabetical order in the directory names due to the initial ordering of the array in the code.

                            As a proper Perl script:

                            #!/usr/bin/perl
                            
                            use strict;
                            use warnings;
                            
                            use English;
                            use Algorithm::Combinatorics qw(combinations);
                            
                            # When interpolating a list in a string (@{$ARG} below), don't use a delimiter
                            local $LIST_SEPARATOR = "";
                            
                            # Get all combinations, and create a directory for each combination
                            map { mkdir "@{$ARG}N" } combinations( [qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4 );
                            

                            This would run pretty much instantaneously and is easily extended to include further words or length of combinations.

                            You would probably be able do something pretty similar in Python…


                            A recursive shell implementation (just for fun, recursive shell functions are seldom very efficient):

                            #!/bin/sh
                            
                            build_combinations () {
                                set_size=$1
                                shift
                            
                                if [ "$set_size" -eq 0 ]; then
                                    printf 'N'
                                else
                                    for token do
                                        shift
                                        for reminder in $(build_combinations "$(( set_size - 1 ))" "$@")
                                        do
                                            printf '%s%sn' "$token" "$reminder"
                                        done
                                    done
                                fi
                            }
                            
                            build_combinations 4 Cr Hf Mo Nb Ta Ti V W Zr | xargs mkdir
                            

                            Idea from having read studog’s answer and inspiration from various bits of an answer to a StackOverflow question.

                            Note that the saving grace of this solution is that the directory names always end with a N. The recursive stop branch outputs N rather than an empty string, which makes the whole thing work. Without it (printing an empty string or a newline), the loop with the command substitution would have nothing to loop over and there would be no output (due to the default value of the IFS variable).

                            share|improve this answer

                            Using Perl and the Algorithm::Combinatorics module:

                            perl -MAlgorithm::Combinatorics=combinations -e '$"=""; map { mkdir "@{$_}N" } combinations([qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4)'
                            

                            This would create the 126 directories that you get from all combinations of four of the included words. Each directory’s name will have a N at the end. The individual words will always occur in alphabetical order in the directory names due to the initial ordering of the array in the code.

                            As a proper Perl script:

                            #!/usr/bin/perl
                            
                            use strict;
                            use warnings;
                            
                            use English;
                            use Algorithm::Combinatorics qw(combinations);
                            
                            # When interpolating a list in a string (@{$ARG} below), don't use a delimiter
                            local $LIST_SEPARATOR = "";
                            
                            # Get all combinations, and create a directory for each combination
                            map { mkdir "@{$ARG}N" } combinations( [qw(Cr Hf Mo Nb Ta Ti V W Zr)], 4 );
                            

                            This would run pretty much instantaneously and is easily extended to include further words or length of combinations.

                            You would probably be able do something pretty similar in Python…


                            A recursive shell implementation (just for fun, recursive shell functions are seldom very efficient):

                            #!/bin/sh
                            
                            build_combinations () {
                                set_size=$1
                                shift
                            
                                if [ "$set_size" -eq 0 ]; then
                                    printf 'N'
                                else
                                    for token do
                                        shift
                                        for reminder in $(build_combinations "$(( set_size - 1 ))" "$@")
                                        do
                                            printf '%s%sn' "$token" "$reminder"
                                        done
                                    done
                                fi
                            }
                            
                            build_combinations 4 Cr Hf Mo Nb Ta Ti V W Zr | xargs mkdir
                            

                            Idea from having read studog’s answer and inspiration from various bits of an answer to a StackOverflow question.

                            Note that the saving grace of this solution is that the directory names always end with a N. The recursive stop branch outputs N rather than an empty string, which makes the whole thing work. Without it (printing an empty string or a newline), the loop with the command substitution would have nothing to loop over and there would be no output (due to the default value of the IFS variable).

                            share|improve this answer

                            share|improve this answer

                            share|improve this answer

                            edited Nov 30 at 8:28

                            answered Nov 29 at 17:35

                            Kusalananda

                            119k16223364

                            119k16223364

                                up vote
                                2
                                down vote

                                An improvement on @n.st’s answer that takes advantage of the fact the elements are in sorted order to start with. It’s also a little clearer in my opinion.

                                #!/bin/bash
                                
                                elements=(Cr Hf Mo Nb Ta Ti V W Zr)
                                len=${#elements[@]}
                                
                                (( a_end = len - 3 ))
                                (( b_end = len - 2 ))
                                (( c_end = len - 1 ))
                                (( d_end = len - 0 ))
                                
                                (( a = 0 ))
                                while (( a < a_end )); do
                                   (( b = a + 1 ))
                                   while (( b < b_end )); do
                                      (( c = b + 1 ))
                                      while (( c < c_end )); do
                                         (( d = c + 1 ))
                                         while (( d < d_end )); do
                                            mkdir "${elements[$a]}${elements[$b]}${elements[$c]}${elements[$d]}"
                                            (( d++ ))
                                         done
                                         (( c++ ))
                                      done
                                      (( b++ ))
                                   done
                                   (( a++ ))
                                done
                                

                                The key part every inner loop starts at the next element index from the enclosing loop. This is a pretty common pattern for generating all combinations of a list of items.

                                Runtime:

                                user@host:~/so$ time ./do.sh 
                                
                                real    0m0.140s
                                user    0m0.085s
                                sys 0m0.044s
                                

                                with

                                user@host:~/so$ ls -1d Cr* Hf* Mo* Nb* Ta* Ti* V* W* Zr* | wc -l
                                ls: cannot access 'V*': No such file or directory
                                ls: cannot access 'W*': No such file or directory
                                ls: cannot access 'Zr*': No such file or directory
                                126
                                

                                share|improve this answer

                                • 1

                                  It looks like this would also lend itself to a recursive implementation, which would make it possible to adjust the number of components of the directory names etc. easier. I haven’t seriously thought about it though.
                                  – Kusalananda
                                  Nov 29 at 21:04

                                • In fact it does lend itself to a recursive implementation! I thought about doing that briefly but decided that the “unrolled” version was more instructive for this particular question.
                                  – studog
                                  Nov 29 at 22:13

                                • Well, I made one.
                                  – Kusalananda
                                  Nov 29 at 22:21

                                up vote
                                2
                                down vote

                                An improvement on @n.st’s answer that takes advantage of the fact the elements are in sorted order to start with. It’s also a little clearer in my opinion.

                                #!/bin/bash
                                
                                elements=(Cr Hf Mo Nb Ta Ti V W Zr)
                                len=${#elements[@]}
                                
                                (( a_end = len - 3 ))
                                (( b_end = len - 2 ))
                                (( c_end = len - 1 ))
                                (( d_end = len - 0 ))
                                
                                (( a = 0 ))
                                while (( a < a_end )); do
                                   (( b = a + 1 ))
                                   while (( b < b_end )); do
                                      (( c = b + 1 ))
                                      while (( c < c_end )); do
                                         (( d = c + 1 ))
                                         while (( d < d_end )); do
                                            mkdir "${elements[$a]}${elements[$b]}${elements[$c]}${elements[$d]}"
                                            (( d++ ))
                                         done
                                         (( c++ ))
                                      done
                                      (( b++ ))
                                   done
                                   (( a++ ))
                                done
                                

                                The key part every inner loop starts at the next element index from the enclosing loop. This is a pretty common pattern for generating all combinations of a list of items.

                                Runtime:

                                user@host:~/so$ time ./do.sh 
                                
                                real    0m0.140s
                                user    0m0.085s
                                sys 0m0.044s
                                

                                with

                                user@host:~/so$ ls -1d Cr* Hf* Mo* Nb* Ta* Ti* V* W* Zr* | wc -l
                                ls: cannot access 'V*': No such file or directory
                                ls: cannot access 'W*': No such file or directory
                                ls: cannot access 'Zr*': No such file or directory
                                126
                                

                                share|improve this answer

                                • 1

                                  It looks like this would also lend itself to a recursive implementation, which would make it possible to adjust the number of components of the directory names etc. easier. I haven’t seriously thought about it though.
                                  – Kusalananda
                                  Nov 29 at 21:04

                                • In fact it does lend itself to a recursive implementation! I thought about doing that briefly but decided that the “unrolled” version was more instructive for this particular question.
                                  – studog
                                  Nov 29 at 22:13

                                • Well, I made one.
                                  – Kusalananda
                                  Nov 29 at 22:21

                                up vote
                                2
                                down vote

                                up vote
                                2
                                down vote

                                An improvement on @n.st’s answer that takes advantage of the fact the elements are in sorted order to start with. It’s also a little clearer in my opinion.

                                #!/bin/bash
                                
                                elements=(Cr Hf Mo Nb Ta Ti V W Zr)
                                len=${#elements[@]}
                                
                                (( a_end = len - 3 ))
                                (( b_end = len - 2 ))
                                (( c_end = len - 1 ))
                                (( d_end = len - 0 ))
                                
                                (( a = 0 ))
                                while (( a < a_end )); do
                                   (( b = a + 1 ))
                                   while (( b < b_end )); do
                                      (( c = b + 1 ))
                                      while (( c < c_end )); do
                                         (( d = c + 1 ))
                                         while (( d < d_end )); do
                                            mkdir "${elements[$a]}${elements[$b]}${elements[$c]}${elements[$d]}"
                                            (( d++ ))
                                         done
                                         (( c++ ))
                                      done
                                      (( b++ ))
                                   done
                                   (( a++ ))
                                done
                                

                                The key part every inner loop starts at the next element index from the enclosing loop. This is a pretty common pattern for generating all combinations of a list of items.

                                Runtime:

                                user@host:~/so$ time ./do.sh 
                                
                                real    0m0.140s
                                user    0m0.085s
                                sys 0m0.044s
                                

                                with

                                user@host:~/so$ ls -1d Cr* Hf* Mo* Nb* Ta* Ti* V* W* Zr* | wc -l
                                ls: cannot access 'V*': No such file or directory
                                ls: cannot access 'W*': No such file or directory
                                ls: cannot access 'Zr*': No such file or directory
                                126
                                

                                share|improve this answer

                                An improvement on @n.st’s answer that takes advantage of the fact the elements are in sorted order to start with. It’s also a little clearer in my opinion.

                                #!/bin/bash
                                
                                elements=(Cr Hf Mo Nb Ta Ti V W Zr)
                                len=${#elements[@]}
                                
                                (( a_end = len - 3 ))
                                (( b_end = len - 2 ))
                                (( c_end = len - 1 ))
                                (( d_end = len - 0 ))
                                
                                (( a = 0 ))
                                while (( a < a_end )); do
                                   (( b = a + 1 ))
                                   while (( b < b_end )); do
                                      (( c = b + 1 ))
                                      while (( c < c_end )); do
                                         (( d = c + 1 ))
                                         while (( d < d_end )); do
                                            mkdir "${elements[$a]}${elements[$b]}${elements[$c]}${elements[$d]}"
                                            (( d++ ))
                                         done
                                         (( c++ ))
                                      done
                                      (( b++ ))
                                   done
                                   (( a++ ))
                                done
                                

                                The key part every inner loop starts at the next element index from the enclosing loop. This is a pretty common pattern for generating all combinations of a list of items.

                                Runtime:

                                user@host:~/so$ time ./do.sh 
                                
                                real    0m0.140s
                                user    0m0.085s
                                sys 0m0.044s
                                

                                with

                                user@host:~/so$ ls -1d Cr* Hf* Mo* Nb* Ta* Ti* V* W* Zr* | wc -l
                                ls: cannot access 'V*': No such file or directory
                                ls: cannot access 'W*': No such file or directory
                                ls: cannot access 'Zr*': No such file or directory
                                126
                                

                                share|improve this answer

                                share|improve this answer

                                share|improve this answer

                                answered Nov 29 at 21:01

                                studog

                                25316

                                25316

                                • 1

                                  It looks like this would also lend itself to a recursive implementation, which would make it possible to adjust the number of components of the directory names etc. easier. I haven’t seriously thought about it though.
                                  – Kusalananda
                                  Nov 29 at 21:04

                                • In fact it does lend itself to a recursive implementation! I thought about doing that briefly but decided that the “unrolled” version was more instructive for this particular question.
                                  – studog
                                  Nov 29 at 22:13

                                • Well, I made one.
                                  – Kusalananda
                                  Nov 29 at 22:21

                                • 1

                                  It looks like this would also lend itself to a recursive implementation, which would make it possible to adjust the number of components of the directory names etc. easier. I haven’t seriously thought about it though.
                                  – Kusalananda
                                  Nov 29 at 21:04

                                • In fact it does lend itself to a recursive implementation! I thought about doing that briefly but decided that the “unrolled” version was more instructive for this particular question.
                                  – studog
                                  Nov 29 at 22:13

                                • Well, I made one.
                                  – Kusalananda
                                  Nov 29 at 22:21

                                1

                                1

                                It looks like this would also lend itself to a recursive implementation, which would make it possible to adjust the number of components of the directory names etc. easier. I haven’t seriously thought about it though.
                                – Kusalananda
                                Nov 29 at 21:04

                                It looks like this would also lend itself to a recursive implementation, which would make it possible to adjust the number of components of the directory names etc. easier. I haven’t seriously thought about it though.
                                – Kusalananda
                                Nov 29 at 21:04

                                In fact it does lend itself to a recursive implementation! I thought about doing that briefly but decided that the “unrolled” version was more instructive for this particular question.
                                – studog
                                Nov 29 at 22:13

                                In fact it does lend itself to a recursive implementation! I thought about doing that briefly but decided that the “unrolled” version was more instructive for this particular question.
                                – studog
                                Nov 29 at 22:13

                                Well, I made one.
                                – Kusalananda
                                Nov 29 at 22:21

                                Well, I made one.
                                – Kusalananda
                                Nov 29 at 22:21

                                draft saved
                                draft discarded

                                Thanks for contributing an answer to Unix & Linux Stack Exchange!

                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid

                                • Asking for help, clarification, or responding to other answers.
                                • Making statements based on opinion; back them up with references or personal experience.

                                To learn more, see our tips on writing great answers.

                                Some of your past answers have not been well-received, and you’re in danger of being blocked from answering.

                                Please pay close attention to the following guidance:

                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid

                                • Asking for help, clarification, or responding to other answers.
                                • Making statements based on opinion; back them up with references or personal experience.

                                To learn more, see our tips on writing great answers.

                                draft saved

                                draft discarded

                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2funix.stackexchange.com%2fquestions%2f484924%2fforce-alphabetical-order-in-for-loop-with-if-conditions%23new-answer’, ‘question_page’);
                                }
                                );

                                Post as a guest

                                Required, but never shown

                                Required, but never shown

                                Required, but never shown

                                Required, but never shown

                                Required, but never shown

                                Required, but never shown

                                Required, but never shown

                                Required, but never shown

                                Required, but never shown

                                Related Post

                                Leave a Reply

                                Your email address will not be published. Required fields are marked *