Loop through find command results that have been added to an array? filenames with gaps treats as 2 entries

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












1















I have created the following code. At the end I want to process each file that is in the array individually but somewhere in this code I have not included the double quotes so the file names with a space in the middle it treats as 2 entries in the array:



#!/bin/bash

EXT=(sh mkv txt)

EXT_OPTS=()
# Now build the find command from the array
for i in "$EXT[@]"; do
EXT_OPTS+=( -o -iname "*.$i" )
done

# remove the first thing in EXT_OPTS
EXT_OPTS=( "$EXT_OPTS[@]:1" )

# Modify to add things to ignore:
EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*test*" -o -iname "*sample*" ')' )

#echo "$EXT_OPTS[@]"

searchResults=($(find . -type f "$EXT_OPTS[@]"))

#echo "$searchResults"

for R in "$searchResults[@]"; do
echo "$R"
sleep 1
done


So the results I am getting are:



./Find2.sh
./untitled
2.sh
./countFiles.sh
./unrar.sh
./untitled
3.sh
./untitled
4.sh
./clearRAM.sh
./bash_test.sh
./Test_Log.txt
./untitled.txt
./Find.txt
./findTestscript.sh
./untitled.sh
./unrarTest.sh
./Test.sh
./Find.sh
./Test_Log
copy.txt
./untitled
5.sh
./IF2.sh


As an example untitled 5.sh has been added to the array as 2 entries.
where have I forgot to add the "s



cheers



EDIT with suggested edits:



#!/bin/bash

EXT=(sh mkv txt)

EXT_OPTS=()
# Now build the find command from the array
for i in "$EXT[@]"; do
EXT_OPTS+=( -o -iname "*.$i" )
done

# remove the first thing in EXT_OPTS
EXT_OPTS=( "$EXT_OPTS[@]:1" )

# Modify to add things to ignore:
#EXT_OPTS=( "$EXT_OPTS[@]:-1" )
EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*x0r*" -o -iname "*torrent*" ')' )

#echo "$EXT_OPTS[@]"

#searchResults=($(find . -type f "$EXT_OPTS[@]"))

#echo "$searchResults"

#for R in "$searchResults[@]"; do
# echo "$R"
# sleep 1
#done


find . -type f "$EXT_OPTS[@]" -exec sh -c '
for pathname do
printf "%sn" "$pathname"
sleep 1
done' sh +


Now Produces:



./Find2.sh
./untitled 2.sh
./countFiles.sh
./unrar.sh
./untitled 3.sh
./Find3.sh
./untitled 4.sh
./clearRAM.sh
./bash_test.sh
./Test_Log.txt
./untitled.txt
./Find.txt
./findTestscript.sh
./untitled.sh
./unrarTest.sh
./Test.sh
./Find.sh
./Test_Log copy.txt
./untitled 5.sh
./IF2.sh
./Find4.sh









share|improve this question




























    1















    I have created the following code. At the end I want to process each file that is in the array individually but somewhere in this code I have not included the double quotes so the file names with a space in the middle it treats as 2 entries in the array:



    #!/bin/bash

    EXT=(sh mkv txt)

    EXT_OPTS=()
    # Now build the find command from the array
    for i in "$EXT[@]"; do
    EXT_OPTS+=( -o -iname "*.$i" )
    done

    # remove the first thing in EXT_OPTS
    EXT_OPTS=( "$EXT_OPTS[@]:1" )

    # Modify to add things to ignore:
    EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*test*" -o -iname "*sample*" ')' )

    #echo "$EXT_OPTS[@]"

    searchResults=($(find . -type f "$EXT_OPTS[@]"))

    #echo "$searchResults"

    for R in "$searchResults[@]"; do
    echo "$R"
    sleep 1
    done


    So the results I am getting are:



    ./Find2.sh
    ./untitled
    2.sh
    ./countFiles.sh
    ./unrar.sh
    ./untitled
    3.sh
    ./untitled
    4.sh
    ./clearRAM.sh
    ./bash_test.sh
    ./Test_Log.txt
    ./untitled.txt
    ./Find.txt
    ./findTestscript.sh
    ./untitled.sh
    ./unrarTest.sh
    ./Test.sh
    ./Find.sh
    ./Test_Log
    copy.txt
    ./untitled
    5.sh
    ./IF2.sh


    As an example untitled 5.sh has been added to the array as 2 entries.
    where have I forgot to add the "s



    cheers



    EDIT with suggested edits:



    #!/bin/bash

    EXT=(sh mkv txt)

    EXT_OPTS=()
    # Now build the find command from the array
    for i in "$EXT[@]"; do
    EXT_OPTS+=( -o -iname "*.$i" )
    done

    # remove the first thing in EXT_OPTS
    EXT_OPTS=( "$EXT_OPTS[@]:1" )

    # Modify to add things to ignore:
    #EXT_OPTS=( "$EXT_OPTS[@]:-1" )
    EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*x0r*" -o -iname "*torrent*" ')' )

    #echo "$EXT_OPTS[@]"

    #searchResults=($(find . -type f "$EXT_OPTS[@]"))

    #echo "$searchResults"

    #for R in "$searchResults[@]"; do
    # echo "$R"
    # sleep 1
    #done


    find . -type f "$EXT_OPTS[@]" -exec sh -c '
    for pathname do
    printf "%sn" "$pathname"
    sleep 1
    done' sh +


    Now Produces:



    ./Find2.sh
    ./untitled 2.sh
    ./countFiles.sh
    ./unrar.sh
    ./untitled 3.sh
    ./Find3.sh
    ./untitled 4.sh
    ./clearRAM.sh
    ./bash_test.sh
    ./Test_Log.txt
    ./untitled.txt
    ./Find.txt
    ./findTestscript.sh
    ./untitled.sh
    ./unrarTest.sh
    ./Test.sh
    ./Find.sh
    ./Test_Log copy.txt
    ./untitled 5.sh
    ./IF2.sh
    ./Find4.sh









    share|improve this question


























      1












      1








      1








      I have created the following code. At the end I want to process each file that is in the array individually but somewhere in this code I have not included the double quotes so the file names with a space in the middle it treats as 2 entries in the array:



      #!/bin/bash

      EXT=(sh mkv txt)

      EXT_OPTS=()
      # Now build the find command from the array
      for i in "$EXT[@]"; do
      EXT_OPTS+=( -o -iname "*.$i" )
      done

      # remove the first thing in EXT_OPTS
      EXT_OPTS=( "$EXT_OPTS[@]:1" )

      # Modify to add things to ignore:
      EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*test*" -o -iname "*sample*" ')' )

      #echo "$EXT_OPTS[@]"

      searchResults=($(find . -type f "$EXT_OPTS[@]"))

      #echo "$searchResults"

      for R in "$searchResults[@]"; do
      echo "$R"
      sleep 1
      done


      So the results I am getting are:



      ./Find2.sh
      ./untitled
      2.sh
      ./countFiles.sh
      ./unrar.sh
      ./untitled
      3.sh
      ./untitled
      4.sh
      ./clearRAM.sh
      ./bash_test.sh
      ./Test_Log.txt
      ./untitled.txt
      ./Find.txt
      ./findTestscript.sh
      ./untitled.sh
      ./unrarTest.sh
      ./Test.sh
      ./Find.sh
      ./Test_Log
      copy.txt
      ./untitled
      5.sh
      ./IF2.sh


      As an example untitled 5.sh has been added to the array as 2 entries.
      where have I forgot to add the "s



      cheers



      EDIT with suggested edits:



      #!/bin/bash

      EXT=(sh mkv txt)

      EXT_OPTS=()
      # Now build the find command from the array
      for i in "$EXT[@]"; do
      EXT_OPTS+=( -o -iname "*.$i" )
      done

      # remove the first thing in EXT_OPTS
      EXT_OPTS=( "$EXT_OPTS[@]:1" )

      # Modify to add things to ignore:
      #EXT_OPTS=( "$EXT_OPTS[@]:-1" )
      EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*x0r*" -o -iname "*torrent*" ')' )

      #echo "$EXT_OPTS[@]"

      #searchResults=($(find . -type f "$EXT_OPTS[@]"))

      #echo "$searchResults"

      #for R in "$searchResults[@]"; do
      # echo "$R"
      # sleep 1
      #done


      find . -type f "$EXT_OPTS[@]" -exec sh -c '
      for pathname do
      printf "%sn" "$pathname"
      sleep 1
      done' sh +


      Now Produces:



      ./Find2.sh
      ./untitled 2.sh
      ./countFiles.sh
      ./unrar.sh
      ./untitled 3.sh
      ./Find3.sh
      ./untitled 4.sh
      ./clearRAM.sh
      ./bash_test.sh
      ./Test_Log.txt
      ./untitled.txt
      ./Find.txt
      ./findTestscript.sh
      ./untitled.sh
      ./unrarTest.sh
      ./Test.sh
      ./Find.sh
      ./Test_Log copy.txt
      ./untitled 5.sh
      ./IF2.sh
      ./Find4.sh









      share|improve this question
















      I have created the following code. At the end I want to process each file that is in the array individually but somewhere in this code I have not included the double quotes so the file names with a space in the middle it treats as 2 entries in the array:



      #!/bin/bash

      EXT=(sh mkv txt)

      EXT_OPTS=()
      # Now build the find command from the array
      for i in "$EXT[@]"; do
      EXT_OPTS+=( -o -iname "*.$i" )
      done

      # remove the first thing in EXT_OPTS
      EXT_OPTS=( "$EXT_OPTS[@]:1" )

      # Modify to add things to ignore:
      EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*test*" -o -iname "*sample*" ')' )

      #echo "$EXT_OPTS[@]"

      searchResults=($(find . -type f "$EXT_OPTS[@]"))

      #echo "$searchResults"

      for R in "$searchResults[@]"; do
      echo "$R"
      sleep 1
      done


      So the results I am getting are:



      ./Find2.sh
      ./untitled
      2.sh
      ./countFiles.sh
      ./unrar.sh
      ./untitled
      3.sh
      ./untitled
      4.sh
      ./clearRAM.sh
      ./bash_test.sh
      ./Test_Log.txt
      ./untitled.txt
      ./Find.txt
      ./findTestscript.sh
      ./untitled.sh
      ./unrarTest.sh
      ./Test.sh
      ./Find.sh
      ./Test_Log
      copy.txt
      ./untitled
      5.sh
      ./IF2.sh


      As an example untitled 5.sh has been added to the array as 2 entries.
      where have I forgot to add the "s



      cheers



      EDIT with suggested edits:



      #!/bin/bash

      EXT=(sh mkv txt)

      EXT_OPTS=()
      # Now build the find command from the array
      for i in "$EXT[@]"; do
      EXT_OPTS+=( -o -iname "*.$i" )
      done

      # remove the first thing in EXT_OPTS
      EXT_OPTS=( "$EXT_OPTS[@]:1" )

      # Modify to add things to ignore:
      #EXT_OPTS=( "$EXT_OPTS[@]:-1" )
      EXT_OPTS=( '(' "$EXT_OPTS[@]" ')' ! '(' -iname "*x0r*" -o -iname "*torrent*" ')' )

      #echo "$EXT_OPTS[@]"

      #searchResults=($(find . -type f "$EXT_OPTS[@]"))

      #echo "$searchResults"

      #for R in "$searchResults[@]"; do
      # echo "$R"
      # sleep 1
      #done


      find . -type f "$EXT_OPTS[@]" -exec sh -c '
      for pathname do
      printf "%sn" "$pathname"
      sleep 1
      done' sh +


      Now Produces:



      ./Find2.sh
      ./untitled 2.sh
      ./countFiles.sh
      ./unrar.sh
      ./untitled 3.sh
      ./Find3.sh
      ./untitled 4.sh
      ./clearRAM.sh
      ./bash_test.sh
      ./Test_Log.txt
      ./untitled.txt
      ./Find.txt
      ./findTestscript.sh
      ./untitled.sh
      ./unrarTest.sh
      ./Test.sh
      ./Find.sh
      ./Test_Log copy.txt
      ./untitled 5.sh
      ./IF2.sh
      ./Find4.sh






      bash shell






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Feb 9 at 0:16







      madmiddle

















      asked Feb 8 at 22:31









      madmiddlemadmiddle

      625




      625




















          2 Answers
          2






          active

          oldest

          votes


















          2














          No, you should not parse the output of find. If you want to do something with the pathnames that find finds, you should do that from within find:



          find ...stuff... -exec sh -c '
          for pathname do
          printf "%sn" "$pathname"
          sleep 1
          done' sh +


          Here, find will call the in-line shell script with batches of found pathnames (the script may be called more than once). find acts as a sort of pathname generator for the internal script.



          Another approach is to use -print0 to output the pathnames with in-between them, and then read them with a tool that knows how to read the nul-terminated pathnames. The nul-character is the only character that is not allowed to be part of a Unix pathname, so that's the only safe way to pass them to another tool.



          Related:



          • Why is looping over find's output bad practice?

          • Understanding the -exec option of `find`





          share|improve this answer























          • I see..... I have not been writing bash for very long so i'm still learning. what I was trying to do was set up the next bit to deal with the various file types. For example if it was a .sh or a .txt files to be copied to one folder and additional to that all the .tmp files go to another folder and then .log files to another folder. What function do I need to read about to do that ? I was going to use a case function but is that the best way to do it?

            – madmiddle
            Feb 8 at 22:53












          • @madmiddle To simplify it, I would make one find for each case. find ... -type f -name '*.tmp' -exec mv -t tmp-files + for .tmp files, for example.

            – Kusalananda
            Feb 8 at 22:58












          • @madmiddle Though you could do it in one huge find command with ( -name '*.tmp' -exec mv ... ) -o ( ... ) -o ( ... ) etc., but it wouldbe ugly and hard to maintain.

            – Kusalananda
            Feb 8 at 23:00












          • thats why I started with the array at the beginning and if i needed to add a new file type then all i needed to do was add to the array at the top and then again at a case statement at the bottom. But like i said I'm still very new to this.

            – madmiddle
            Feb 8 at 23:03











          • @madmiddle The issue is fully described and explained in the first question I linked to in my answer. The shell will split all found pathnames on spaces, tabs and newlines (by default) and your loop will loop over these split-up words.

            – Kusalananda
            Feb 8 at 23:04



















          1














          With newer versions of bash (> 4.4 IIRC), the mapfile builtin allows you to specify a null delimter - you can then use find ... print0 as suggested in Kusalananda's answer e.g.



          mapfile -t -d '' searchResults < <(find . -type f "$EXT_OPTS[@]" -print0)


          If that's not an option, then a slower uglier way would be something like



          while IFS= read -r -d '' f; do 
          searchResults+=("$f")
          done < <(find . -type f "$EXT_OPTS[@]" -print0)


          See the related bash: whitespace-safe procedural use of find into select






          share|improve this answer






















            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',
            autoActivateHeartbeat: false,
            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%2f499574%2floop-through-find-command-results-that-have-been-added-to-an-array-filenames-wi%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            No, you should not parse the output of find. If you want to do something with the pathnames that find finds, you should do that from within find:



            find ...stuff... -exec sh -c '
            for pathname do
            printf "%sn" "$pathname"
            sleep 1
            done' sh +


            Here, find will call the in-line shell script with batches of found pathnames (the script may be called more than once). find acts as a sort of pathname generator for the internal script.



            Another approach is to use -print0 to output the pathnames with in-between them, and then read them with a tool that knows how to read the nul-terminated pathnames. The nul-character is the only character that is not allowed to be part of a Unix pathname, so that's the only safe way to pass them to another tool.



            Related:



            • Why is looping over find's output bad practice?

            • Understanding the -exec option of `find`





            share|improve this answer























            • I see..... I have not been writing bash for very long so i'm still learning. what I was trying to do was set up the next bit to deal with the various file types. For example if it was a .sh or a .txt files to be copied to one folder and additional to that all the .tmp files go to another folder and then .log files to another folder. What function do I need to read about to do that ? I was going to use a case function but is that the best way to do it?

              – madmiddle
              Feb 8 at 22:53












            • @madmiddle To simplify it, I would make one find for each case. find ... -type f -name '*.tmp' -exec mv -t tmp-files + for .tmp files, for example.

              – Kusalananda
              Feb 8 at 22:58












            • @madmiddle Though you could do it in one huge find command with ( -name '*.tmp' -exec mv ... ) -o ( ... ) -o ( ... ) etc., but it wouldbe ugly and hard to maintain.

              – Kusalananda
              Feb 8 at 23:00












            • thats why I started with the array at the beginning and if i needed to add a new file type then all i needed to do was add to the array at the top and then again at a case statement at the bottom. But like i said I'm still very new to this.

              – madmiddle
              Feb 8 at 23:03











            • @madmiddle The issue is fully described and explained in the first question I linked to in my answer. The shell will split all found pathnames on spaces, tabs and newlines (by default) and your loop will loop over these split-up words.

              – Kusalananda
              Feb 8 at 23:04
















            2














            No, you should not parse the output of find. If you want to do something with the pathnames that find finds, you should do that from within find:



            find ...stuff... -exec sh -c '
            for pathname do
            printf "%sn" "$pathname"
            sleep 1
            done' sh +


            Here, find will call the in-line shell script with batches of found pathnames (the script may be called more than once). find acts as a sort of pathname generator for the internal script.



            Another approach is to use -print0 to output the pathnames with in-between them, and then read them with a tool that knows how to read the nul-terminated pathnames. The nul-character is the only character that is not allowed to be part of a Unix pathname, so that's the only safe way to pass them to another tool.



            Related:



            • Why is looping over find's output bad practice?

            • Understanding the -exec option of `find`





            share|improve this answer























            • I see..... I have not been writing bash for very long so i'm still learning. what I was trying to do was set up the next bit to deal with the various file types. For example if it was a .sh or a .txt files to be copied to one folder and additional to that all the .tmp files go to another folder and then .log files to another folder. What function do I need to read about to do that ? I was going to use a case function but is that the best way to do it?

              – madmiddle
              Feb 8 at 22:53












            • @madmiddle To simplify it, I would make one find for each case. find ... -type f -name '*.tmp' -exec mv -t tmp-files + for .tmp files, for example.

              – Kusalananda
              Feb 8 at 22:58












            • @madmiddle Though you could do it in one huge find command with ( -name '*.tmp' -exec mv ... ) -o ( ... ) -o ( ... ) etc., but it wouldbe ugly and hard to maintain.

              – Kusalananda
              Feb 8 at 23:00












            • thats why I started with the array at the beginning and if i needed to add a new file type then all i needed to do was add to the array at the top and then again at a case statement at the bottom. But like i said I'm still very new to this.

              – madmiddle
              Feb 8 at 23:03











            • @madmiddle The issue is fully described and explained in the first question I linked to in my answer. The shell will split all found pathnames on spaces, tabs and newlines (by default) and your loop will loop over these split-up words.

              – Kusalananda
              Feb 8 at 23:04














            2












            2








            2







            No, you should not parse the output of find. If you want to do something with the pathnames that find finds, you should do that from within find:



            find ...stuff... -exec sh -c '
            for pathname do
            printf "%sn" "$pathname"
            sleep 1
            done' sh +


            Here, find will call the in-line shell script with batches of found pathnames (the script may be called more than once). find acts as a sort of pathname generator for the internal script.



            Another approach is to use -print0 to output the pathnames with in-between them, and then read them with a tool that knows how to read the nul-terminated pathnames. The nul-character is the only character that is not allowed to be part of a Unix pathname, so that's the only safe way to pass them to another tool.



            Related:



            • Why is looping over find's output bad practice?

            • Understanding the -exec option of `find`





            share|improve this answer













            No, you should not parse the output of find. If you want to do something with the pathnames that find finds, you should do that from within find:



            find ...stuff... -exec sh -c '
            for pathname do
            printf "%sn" "$pathname"
            sleep 1
            done' sh +


            Here, find will call the in-line shell script with batches of found pathnames (the script may be called more than once). find acts as a sort of pathname generator for the internal script.



            Another approach is to use -print0 to output the pathnames with in-between them, and then read them with a tool that knows how to read the nul-terminated pathnames. The nul-character is the only character that is not allowed to be part of a Unix pathname, so that's the only safe way to pass them to another tool.



            Related:



            • Why is looping over find's output bad practice?

            • Understanding the -exec option of `find`






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Feb 8 at 22:42









            KusalanandaKusalananda

            133k17254417




            133k17254417












            • I see..... I have not been writing bash for very long so i'm still learning. what I was trying to do was set up the next bit to deal with the various file types. For example if it was a .sh or a .txt files to be copied to one folder and additional to that all the .tmp files go to another folder and then .log files to another folder. What function do I need to read about to do that ? I was going to use a case function but is that the best way to do it?

              – madmiddle
              Feb 8 at 22:53












            • @madmiddle To simplify it, I would make one find for each case. find ... -type f -name '*.tmp' -exec mv -t tmp-files + for .tmp files, for example.

              – Kusalananda
              Feb 8 at 22:58












            • @madmiddle Though you could do it in one huge find command with ( -name '*.tmp' -exec mv ... ) -o ( ... ) -o ( ... ) etc., but it wouldbe ugly and hard to maintain.

              – Kusalananda
              Feb 8 at 23:00












            • thats why I started with the array at the beginning and if i needed to add a new file type then all i needed to do was add to the array at the top and then again at a case statement at the bottom. But like i said I'm still very new to this.

              – madmiddle
              Feb 8 at 23:03











            • @madmiddle The issue is fully described and explained in the first question I linked to in my answer. The shell will split all found pathnames on spaces, tabs and newlines (by default) and your loop will loop over these split-up words.

              – Kusalananda
              Feb 8 at 23:04


















            • I see..... I have not been writing bash for very long so i'm still learning. what I was trying to do was set up the next bit to deal with the various file types. For example if it was a .sh or a .txt files to be copied to one folder and additional to that all the .tmp files go to another folder and then .log files to another folder. What function do I need to read about to do that ? I was going to use a case function but is that the best way to do it?

              – madmiddle
              Feb 8 at 22:53












            • @madmiddle To simplify it, I would make one find for each case. find ... -type f -name '*.tmp' -exec mv -t tmp-files + for .tmp files, for example.

              – Kusalananda
              Feb 8 at 22:58












            • @madmiddle Though you could do it in one huge find command with ( -name '*.tmp' -exec mv ... ) -o ( ... ) -o ( ... ) etc., but it wouldbe ugly and hard to maintain.

              – Kusalananda
              Feb 8 at 23:00












            • thats why I started with the array at the beginning and if i needed to add a new file type then all i needed to do was add to the array at the top and then again at a case statement at the bottom. But like i said I'm still very new to this.

              – madmiddle
              Feb 8 at 23:03











            • @madmiddle The issue is fully described and explained in the first question I linked to in my answer. The shell will split all found pathnames on spaces, tabs and newlines (by default) and your loop will loop over these split-up words.

              – Kusalananda
              Feb 8 at 23:04

















            I see..... I have not been writing bash for very long so i'm still learning. what I was trying to do was set up the next bit to deal with the various file types. For example if it was a .sh or a .txt files to be copied to one folder and additional to that all the .tmp files go to another folder and then .log files to another folder. What function do I need to read about to do that ? I was going to use a case function but is that the best way to do it?

            – madmiddle
            Feb 8 at 22:53






            I see..... I have not been writing bash for very long so i'm still learning. what I was trying to do was set up the next bit to deal with the various file types. For example if it was a .sh or a .txt files to be copied to one folder and additional to that all the .tmp files go to another folder and then .log files to another folder. What function do I need to read about to do that ? I was going to use a case function but is that the best way to do it?

            – madmiddle
            Feb 8 at 22:53














            @madmiddle To simplify it, I would make one find for each case. find ... -type f -name '*.tmp' -exec mv -t tmp-files + for .tmp files, for example.

            – Kusalananda
            Feb 8 at 22:58






            @madmiddle To simplify it, I would make one find for each case. find ... -type f -name '*.tmp' -exec mv -t tmp-files + for .tmp files, for example.

            – Kusalananda
            Feb 8 at 22:58














            @madmiddle Though you could do it in one huge find command with ( -name '*.tmp' -exec mv ... ) -o ( ... ) -o ( ... ) etc., but it wouldbe ugly and hard to maintain.

            – Kusalananda
            Feb 8 at 23:00






            @madmiddle Though you could do it in one huge find command with ( -name '*.tmp' -exec mv ... ) -o ( ... ) -o ( ... ) etc., but it wouldbe ugly and hard to maintain.

            – Kusalananda
            Feb 8 at 23:00














            thats why I started with the array at the beginning and if i needed to add a new file type then all i needed to do was add to the array at the top and then again at a case statement at the bottom. But like i said I'm still very new to this.

            – madmiddle
            Feb 8 at 23:03





            thats why I started with the array at the beginning and if i needed to add a new file type then all i needed to do was add to the array at the top and then again at a case statement at the bottom. But like i said I'm still very new to this.

            – madmiddle
            Feb 8 at 23:03













            @madmiddle The issue is fully described and explained in the first question I linked to in my answer. The shell will split all found pathnames on spaces, tabs and newlines (by default) and your loop will loop over these split-up words.

            – Kusalananda
            Feb 8 at 23:04






            @madmiddle The issue is fully described and explained in the first question I linked to in my answer. The shell will split all found pathnames on spaces, tabs and newlines (by default) and your loop will loop over these split-up words.

            – Kusalananda
            Feb 8 at 23:04














            1














            With newer versions of bash (> 4.4 IIRC), the mapfile builtin allows you to specify a null delimter - you can then use find ... print0 as suggested in Kusalananda's answer e.g.



            mapfile -t -d '' searchResults < <(find . -type f "$EXT_OPTS[@]" -print0)


            If that's not an option, then a slower uglier way would be something like



            while IFS= read -r -d '' f; do 
            searchResults+=("$f")
            done < <(find . -type f "$EXT_OPTS[@]" -print0)


            See the related bash: whitespace-safe procedural use of find into select






            share|improve this answer



























              1














              With newer versions of bash (> 4.4 IIRC), the mapfile builtin allows you to specify a null delimter - you can then use find ... print0 as suggested in Kusalananda's answer e.g.



              mapfile -t -d '' searchResults < <(find . -type f "$EXT_OPTS[@]" -print0)


              If that's not an option, then a slower uglier way would be something like



              while IFS= read -r -d '' f; do 
              searchResults+=("$f")
              done < <(find . -type f "$EXT_OPTS[@]" -print0)


              See the related bash: whitespace-safe procedural use of find into select






              share|improve this answer

























                1












                1








                1







                With newer versions of bash (> 4.4 IIRC), the mapfile builtin allows you to specify a null delimter - you can then use find ... print0 as suggested in Kusalananda's answer e.g.



                mapfile -t -d '' searchResults < <(find . -type f "$EXT_OPTS[@]" -print0)


                If that's not an option, then a slower uglier way would be something like



                while IFS= read -r -d '' f; do 
                searchResults+=("$f")
                done < <(find . -type f "$EXT_OPTS[@]" -print0)


                See the related bash: whitespace-safe procedural use of find into select






                share|improve this answer













                With newer versions of bash (> 4.4 IIRC), the mapfile builtin allows you to specify a null delimter - you can then use find ... print0 as suggested in Kusalananda's answer e.g.



                mapfile -t -d '' searchResults < <(find . -type f "$EXT_OPTS[@]" -print0)


                If that's not an option, then a slower uglier way would be something like



                while IFS= read -r -d '' f; do 
                searchResults+=("$f")
                done < <(find . -type f "$EXT_OPTS[@]" -print0)


                See the related bash: whitespace-safe procedural use of find into select







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Feb 8 at 23:13









                steeldriversteeldriver

                36.5k35286




                36.5k35286



























                    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.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f499574%2floop-through-find-command-results-that-have-been-added-to-an-array-filenames-wi%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






                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Displaying single band from multi-band raster using QGIS

                    How many registers does an x86_64 CPU actually have?