shell script to remove files didn't work












3















I want to delete multiple images having resolution less then 228x228.
For that, I wrote this shell script:



#!/bin/bash

for i in $( ls ); do
if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
then
rm $i
fi
done


For some reasons, I got this output when I run it:



./del.sh: line 4: [640: command not found
./del.sh: line 4: [550: command not found
./del.sh: line 4: [315: command not found
...


Could you please tell me what's wrong in this script and how to fix it.

Thank you.



EDIT: Even after I added spaces after the brackets, I still got an error. It was due to the usage of < instead of -lt and has been fixed. Now there is no error.










share|improve this question




















  • 4





    Why not parse ls (and what do to instead)?

    – dessert
    Jan 11 at 12:39






  • 1





    You need spaces after [ and before ].

    – Ralf
    Jan 11 at 14:04






  • 1





    Possible duplicate of what is wrong with this piece of code?

    – Barmar
    Jan 11 at 16:35











  • @PerlDuck Thanks? I only showed up because this was in Hot Questions, don't expect me to show up regularly.

    – Barmar
    Jan 11 at 22:35






  • 1





    Please never use the output of $( ls ) in a script, because ls doesn't have a universal standard. It's anyway more readable and more efficient in the loop to use for i in *; do.

    – Paddy Landau
    Jan 15 at 10:58
















3















I want to delete multiple images having resolution less then 228x228.
For that, I wrote this shell script:



#!/bin/bash

for i in $( ls ); do
if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
then
rm $i
fi
done


For some reasons, I got this output when I run it:



./del.sh: line 4: [640: command not found
./del.sh: line 4: [550: command not found
./del.sh: line 4: [315: command not found
...


Could you please tell me what's wrong in this script and how to fix it.

Thank you.



EDIT: Even after I added spaces after the brackets, I still got an error. It was due to the usage of < instead of -lt and has been fixed. Now there is no error.










share|improve this question




















  • 4





    Why not parse ls (and what do to instead)?

    – dessert
    Jan 11 at 12:39






  • 1





    You need spaces after [ and before ].

    – Ralf
    Jan 11 at 14:04






  • 1





    Possible duplicate of what is wrong with this piece of code?

    – Barmar
    Jan 11 at 16:35











  • @PerlDuck Thanks? I only showed up because this was in Hot Questions, don't expect me to show up regularly.

    – Barmar
    Jan 11 at 22:35






  • 1





    Please never use the output of $( ls ) in a script, because ls doesn't have a universal standard. It's anyway more readable and more efficient in the loop to use for i in *; do.

    – Paddy Landau
    Jan 15 at 10:58














3












3








3


1






I want to delete multiple images having resolution less then 228x228.
For that, I wrote this shell script:



#!/bin/bash

for i in $( ls ); do
if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
then
rm $i
fi
done


For some reasons, I got this output when I run it:



./del.sh: line 4: [640: command not found
./del.sh: line 4: [550: command not found
./del.sh: line 4: [315: command not found
...


Could you please tell me what's wrong in this script and how to fix it.

Thank you.



EDIT: Even after I added spaces after the brackets, I still got an error. It was due to the usage of < instead of -lt and has been fixed. Now there is no error.










share|improve this question
















I want to delete multiple images having resolution less then 228x228.
For that, I wrote this shell script:



#!/bin/bash

for i in $( ls ); do
if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
then
rm $i
fi
done


For some reasons, I got this output when I run it:



./del.sh: line 4: [640: command not found
./del.sh: line 4: [550: command not found
./del.sh: line 4: [315: command not found
...


Could you please tell me what's wrong in this script and how to fix it.

Thank you.



EDIT: Even after I added spaces after the brackets, I still got an error. It was due to the usage of < instead of -lt and has been fixed. Now there is no error.







command-line bash scripts






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 11 at 19:36









Captain Man

151312




151312










asked Jan 11 at 10:09









singriumsingrium

1,131422




1,131422








  • 4





    Why not parse ls (and what do to instead)?

    – dessert
    Jan 11 at 12:39






  • 1





    You need spaces after [ and before ].

    – Ralf
    Jan 11 at 14:04






  • 1





    Possible duplicate of what is wrong with this piece of code?

    – Barmar
    Jan 11 at 16:35











  • @PerlDuck Thanks? I only showed up because this was in Hot Questions, don't expect me to show up regularly.

    – Barmar
    Jan 11 at 22:35






  • 1





    Please never use the output of $( ls ) in a script, because ls doesn't have a universal standard. It's anyway more readable and more efficient in the loop to use for i in *; do.

    – Paddy Landau
    Jan 15 at 10:58














  • 4





    Why not parse ls (and what do to instead)?

    – dessert
    Jan 11 at 12:39






  • 1





    You need spaces after [ and before ].

    – Ralf
    Jan 11 at 14:04






  • 1





    Possible duplicate of what is wrong with this piece of code?

    – Barmar
    Jan 11 at 16:35











  • @PerlDuck Thanks? I only showed up because this was in Hot Questions, don't expect me to show up regularly.

    – Barmar
    Jan 11 at 22:35






  • 1





    Please never use the output of $( ls ) in a script, because ls doesn't have a universal standard. It's anyway more readable and more efficient in the loop to use for i in *; do.

    – Paddy Landau
    Jan 15 at 10:58








4




4





Why not parse ls (and what do to instead)?

– dessert
Jan 11 at 12:39





Why not parse ls (and what do to instead)?

– dessert
Jan 11 at 12:39




1




1





You need spaces after [ and before ].

– Ralf
Jan 11 at 14:04





You need spaces after [ and before ].

– Ralf
Jan 11 at 14:04




1




1





Possible duplicate of what is wrong with this piece of code?

– Barmar
Jan 11 at 16:35





Possible duplicate of what is wrong with this piece of code?

– Barmar
Jan 11 at 16:35













@PerlDuck Thanks? I only showed up because this was in Hot Questions, don't expect me to show up regularly.

– Barmar
Jan 11 at 22:35





@PerlDuck Thanks? I only showed up because this was in Hot Questions, don't expect me to show up regularly.

– Barmar
Jan 11 at 22:35




1




1





Please never use the output of $( ls ) in a script, because ls doesn't have a universal standard. It's anyway more readable and more efficient in the loop to use for i in *; do.

– Paddy Landau
Jan 15 at 10:58





Please never use the output of $( ls ) in a script, because ls doesn't have a universal standard. It's anyway more readable and more efficient in the loop to use for i in *; do.

– Paddy Landau
Jan 15 at 10:58










3 Answers
3






active

oldest

votes


















11














Some issues here: Firstly, the expression in a […] test needs spaces around it (pitfall #10), and secondly
the comparison < doesn't work with […] tests (pitfall #7). You either need -lt (less than)
or use [[…]] instead, which is a bashism. Also, the for loop should be replaced (pitfall #1).



So:



for i in ./*; do
if [ -e "$i" ]; then
if [ $(identify -format "%w" "$i") -lt 228 ] && [ $(identify -format "%h" "$i") -lt 228 ];
then
rm -- "$i"
fi
fi
done


You may also want to avoid calling identify twice to get the two dimensions (pitfall #58) but call
it just once instead and let it print a string ready to be used as variable assignments in shell syntax.



If we write



identify -format "width=%w height=%h" "$i"


it will print something like width=50 heigth=250. When we evaluate that string then we have set two variables with just one call and the condition can be written as:



eval "$(identify -format "width=%w height=%h" "$i")"
if [ $width -lt 228 ] && [ $height -lt 228 ];
then
rm -- "$i"
fi


See also: common bash pitfalls.






share|improve this answer

































    6














    Instead of a loop, I'd use find with -exec and -delete:



    find . -maxdepth 1 -type f  
    -exec sh -c '
    [ $(identify -format "%w" "$1") -lt 228 ] &&
    [ $(identify -format "%h" "$1") -lt 228 ]' _ {} ;
    -delete -print


    This will also print the files that get deleted, you can remove -print if you don't want that.






    share|improve this answer





















    • 1





      "This will also print the files that get deleted, you can remove -print if you don't want that." Or remove the -delete and run it once as a dry run to sanity check before restoring it and running for real.

      – Kevin
      Jan 11 at 23:09



















    3














    Not intended to answer but to give a useful tip that helped me much doing bash scripting.



    There's a shell script linter called shellcheck that might trap some common errors in bash scripts and also avoid some pitfalls. It can be installed like any package in ubuntu -> https://launchpad.net/ubuntu/+source/shellcheck is in universe for current stable.



    This is the output for your script



    shellcheck del.sh

    In del.sh line 4:
    if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
    ^-- SC1009: The mentioned parser error was in this if expression.
    ^-- SC1073: Couldn't parse this test expression.
    ^-- SC1035: You need a space after the [ and before the ].
    ^-- SC1020: You need a space before the ].
    ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.


    If you fix and apply again you'll get some other recommendations and fixes already mentioned in the accepted answer.






    share|improve this answer























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "89"
      };
      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: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      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%2faskubuntu.com%2fquestions%2f1108810%2fshell-script-to-remove-files-didnt-work%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      11














      Some issues here: Firstly, the expression in a […] test needs spaces around it (pitfall #10), and secondly
      the comparison < doesn't work with […] tests (pitfall #7). You either need -lt (less than)
      or use [[…]] instead, which is a bashism. Also, the for loop should be replaced (pitfall #1).



      So:



      for i in ./*; do
      if [ -e "$i" ]; then
      if [ $(identify -format "%w" "$i") -lt 228 ] && [ $(identify -format "%h" "$i") -lt 228 ];
      then
      rm -- "$i"
      fi
      fi
      done


      You may also want to avoid calling identify twice to get the two dimensions (pitfall #58) but call
      it just once instead and let it print a string ready to be used as variable assignments in shell syntax.



      If we write



      identify -format "width=%w height=%h" "$i"


      it will print something like width=50 heigth=250. When we evaluate that string then we have set two variables with just one call and the condition can be written as:



      eval "$(identify -format "width=%w height=%h" "$i")"
      if [ $width -lt 228 ] && [ $height -lt 228 ];
      then
      rm -- "$i"
      fi


      See also: common bash pitfalls.






      share|improve this answer






























        11














        Some issues here: Firstly, the expression in a […] test needs spaces around it (pitfall #10), and secondly
        the comparison < doesn't work with […] tests (pitfall #7). You either need -lt (less than)
        or use [[…]] instead, which is a bashism. Also, the for loop should be replaced (pitfall #1).



        So:



        for i in ./*; do
        if [ -e "$i" ]; then
        if [ $(identify -format "%w" "$i") -lt 228 ] && [ $(identify -format "%h" "$i") -lt 228 ];
        then
        rm -- "$i"
        fi
        fi
        done


        You may also want to avoid calling identify twice to get the two dimensions (pitfall #58) but call
        it just once instead and let it print a string ready to be used as variable assignments in shell syntax.



        If we write



        identify -format "width=%w height=%h" "$i"


        it will print something like width=50 heigth=250. When we evaluate that string then we have set two variables with just one call and the condition can be written as:



        eval "$(identify -format "width=%w height=%h" "$i")"
        if [ $width -lt 228 ] && [ $height -lt 228 ];
        then
        rm -- "$i"
        fi


        See also: common bash pitfalls.






        share|improve this answer




























          11












          11








          11







          Some issues here: Firstly, the expression in a […] test needs spaces around it (pitfall #10), and secondly
          the comparison < doesn't work with […] tests (pitfall #7). You either need -lt (less than)
          or use [[…]] instead, which is a bashism. Also, the for loop should be replaced (pitfall #1).



          So:



          for i in ./*; do
          if [ -e "$i" ]; then
          if [ $(identify -format "%w" "$i") -lt 228 ] && [ $(identify -format "%h" "$i") -lt 228 ];
          then
          rm -- "$i"
          fi
          fi
          done


          You may also want to avoid calling identify twice to get the two dimensions (pitfall #58) but call
          it just once instead and let it print a string ready to be used as variable assignments in shell syntax.



          If we write



          identify -format "width=%w height=%h" "$i"


          it will print something like width=50 heigth=250. When we evaluate that string then we have set two variables with just one call and the condition can be written as:



          eval "$(identify -format "width=%w height=%h" "$i")"
          if [ $width -lt 228 ] && [ $height -lt 228 ];
          then
          rm -- "$i"
          fi


          See also: common bash pitfalls.






          share|improve this answer















          Some issues here: Firstly, the expression in a […] test needs spaces around it (pitfall #10), and secondly
          the comparison < doesn't work with […] tests (pitfall #7). You either need -lt (less than)
          or use [[…]] instead, which is a bashism. Also, the for loop should be replaced (pitfall #1).



          So:



          for i in ./*; do
          if [ -e "$i" ]; then
          if [ $(identify -format "%w" "$i") -lt 228 ] && [ $(identify -format "%h" "$i") -lt 228 ];
          then
          rm -- "$i"
          fi
          fi
          done


          You may also want to avoid calling identify twice to get the two dimensions (pitfall #58) but call
          it just once instead and let it print a string ready to be used as variable assignments in shell syntax.



          If we write



          identify -format "width=%w height=%h" "$i"


          it will print something like width=50 heigth=250. When we evaluate that string then we have set two variables with just one call and the condition can be written as:



          eval "$(identify -format "width=%w height=%h" "$i")"
          if [ $width -lt 228 ] && [ $height -lt 228 ];
          then
          rm -- "$i"
          fi


          See also: common bash pitfalls.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 11 at 13:44









          dessert

          22.4k56298




          22.4k56298










          answered Jan 11 at 10:28









          PerlDuckPerlDuck

          5,86211333




          5,86211333

























              6














              Instead of a loop, I'd use find with -exec and -delete:



              find . -maxdepth 1 -type f  
              -exec sh -c '
              [ $(identify -format "%w" "$1") -lt 228 ] &&
              [ $(identify -format "%h" "$1") -lt 228 ]' _ {} ;
              -delete -print


              This will also print the files that get deleted, you can remove -print if you don't want that.






              share|improve this answer





















              • 1





                "This will also print the files that get deleted, you can remove -print if you don't want that." Or remove the -delete and run it once as a dry run to sanity check before restoring it and running for real.

                – Kevin
                Jan 11 at 23:09
















              6














              Instead of a loop, I'd use find with -exec and -delete:



              find . -maxdepth 1 -type f  
              -exec sh -c '
              [ $(identify -format "%w" "$1") -lt 228 ] &&
              [ $(identify -format "%h" "$1") -lt 228 ]' _ {} ;
              -delete -print


              This will also print the files that get deleted, you can remove -print if you don't want that.






              share|improve this answer





















              • 1





                "This will also print the files that get deleted, you can remove -print if you don't want that." Or remove the -delete and run it once as a dry run to sanity check before restoring it and running for real.

                – Kevin
                Jan 11 at 23:09














              6












              6








              6







              Instead of a loop, I'd use find with -exec and -delete:



              find . -maxdepth 1 -type f  
              -exec sh -c '
              [ $(identify -format "%w" "$1") -lt 228 ] &&
              [ $(identify -format "%h" "$1") -lt 228 ]' _ {} ;
              -delete -print


              This will also print the files that get deleted, you can remove -print if you don't want that.






              share|improve this answer















              Instead of a loop, I'd use find with -exec and -delete:



              find . -maxdepth 1 -type f  
              -exec sh -c '
              [ $(identify -format "%w" "$1") -lt 228 ] &&
              [ $(identify -format "%h" "$1") -lt 228 ]' _ {} ;
              -delete -print


              This will also print the files that get deleted, you can remove -print if you don't want that.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 11 at 12:16

























              answered Jan 11 at 12:10









              RoVoRoVo

              7,1911741




              7,1911741








              • 1





                "This will also print the files that get deleted, you can remove -print if you don't want that." Or remove the -delete and run it once as a dry run to sanity check before restoring it and running for real.

                – Kevin
                Jan 11 at 23:09














              • 1





                "This will also print the files that get deleted, you can remove -print if you don't want that." Or remove the -delete and run it once as a dry run to sanity check before restoring it and running for real.

                – Kevin
                Jan 11 at 23:09








              1




              1





              "This will also print the files that get deleted, you can remove -print if you don't want that." Or remove the -delete and run it once as a dry run to sanity check before restoring it and running for real.

              – Kevin
              Jan 11 at 23:09





              "This will also print the files that get deleted, you can remove -print if you don't want that." Or remove the -delete and run it once as a dry run to sanity check before restoring it and running for real.

              – Kevin
              Jan 11 at 23:09











              3














              Not intended to answer but to give a useful tip that helped me much doing bash scripting.



              There's a shell script linter called shellcheck that might trap some common errors in bash scripts and also avoid some pitfalls. It can be installed like any package in ubuntu -> https://launchpad.net/ubuntu/+source/shellcheck is in universe for current stable.



              This is the output for your script



              shellcheck del.sh

              In del.sh line 4:
              if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
              ^-- SC1009: The mentioned parser error was in this if expression.
              ^-- SC1073: Couldn't parse this test expression.
              ^-- SC1035: You need a space after the [ and before the ].
              ^-- SC1020: You need a space before the ].
              ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.


              If you fix and apply again you'll get some other recommendations and fixes already mentioned in the accepted answer.






              share|improve this answer




























                3














                Not intended to answer but to give a useful tip that helped me much doing bash scripting.



                There's a shell script linter called shellcheck that might trap some common errors in bash scripts and also avoid some pitfalls. It can be installed like any package in ubuntu -> https://launchpad.net/ubuntu/+source/shellcheck is in universe for current stable.



                This is the output for your script



                shellcheck del.sh

                In del.sh line 4:
                if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
                ^-- SC1009: The mentioned parser error was in this if expression.
                ^-- SC1073: Couldn't parse this test expression.
                ^-- SC1035: You need a space after the [ and before the ].
                ^-- SC1020: You need a space before the ].
                ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.


                If you fix and apply again you'll get some other recommendations and fixes already mentioned in the accepted answer.






                share|improve this answer


























                  3












                  3








                  3







                  Not intended to answer but to give a useful tip that helped me much doing bash scripting.



                  There's a shell script linter called shellcheck that might trap some common errors in bash scripts and also avoid some pitfalls. It can be installed like any package in ubuntu -> https://launchpad.net/ubuntu/+source/shellcheck is in universe for current stable.



                  This is the output for your script



                  shellcheck del.sh

                  In del.sh line 4:
                  if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
                  ^-- SC1009: The mentioned parser error was in this if expression.
                  ^-- SC1073: Couldn't parse this test expression.
                  ^-- SC1035: You need a space after the [ and before the ].
                  ^-- SC1020: You need a space before the ].
                  ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.


                  If you fix and apply again you'll get some other recommendations and fixes already mentioned in the accepted answer.






                  share|improve this answer













                  Not intended to answer but to give a useful tip that helped me much doing bash scripting.



                  There's a shell script linter called shellcheck that might trap some common errors in bash scripts and also avoid some pitfalls. It can be installed like any package in ubuntu -> https://launchpad.net/ubuntu/+source/shellcheck is in universe for current stable.



                  This is the output for your script



                  shellcheck del.sh

                  In del.sh line 4:
                  if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
                  ^-- SC1009: The mentioned parser error was in this if expression.
                  ^-- SC1073: Couldn't parse this test expression.
                  ^-- SC1035: You need a space after the [ and before the ].
                  ^-- SC1020: You need a space before the ].
                  ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.


                  If you fix and apply again you'll get some other recommendations and fixes already mentioned in the accepted answer.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 11 at 12:56









                  theisttheist

                  68249




                  68249






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Ask Ubuntu!


                      • 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%2faskubuntu.com%2fquestions%2f1108810%2fshell-script-to-remove-files-didnt-work%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

                      Mario Kart Wii

                      What does “Dominus providebit” mean?

                      Antonio Litta Visconti Arese