how to delete (or keep) certain file extensions using busybox find?

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











up vote
3
down vote

favorite












I have a folder which contains files (various file extensions) and subfolders. I want to keep certain file extensions and delete the rest.



e.g. keep all .txt and .jpg files and delete all other files.


on regular UNIX/GNU, I can use find together with the "-not" parameter to achieve this.



> find . -not -name "*.jpg" -not -name "*txt" -type f -delete


But sadly, this parameter is not available on busybox find.



Any ideas on how it can be done? Thanks a lot










share|improve this question

























    up vote
    3
    down vote

    favorite












    I have a folder which contains files (various file extensions) and subfolders. I want to keep certain file extensions and delete the rest.



    e.g. keep all .txt and .jpg files and delete all other files.


    on regular UNIX/GNU, I can use find together with the "-not" parameter to achieve this.



    > find . -not -name "*.jpg" -not -name "*txt" -type f -delete


    But sadly, this parameter is not available on busybox find.



    Any ideas on how it can be done? Thanks a lot










    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I have a folder which contains files (various file extensions) and subfolders. I want to keep certain file extensions and delete the rest.



      e.g. keep all .txt and .jpg files and delete all other files.


      on regular UNIX/GNU, I can use find together with the "-not" parameter to achieve this.



      > find . -not -name "*.jpg" -not -name "*txt" -type f -delete


      But sadly, this parameter is not available on busybox find.



      Any ideas on how it can be done? Thanks a lot










      share|improve this question













      I have a folder which contains files (various file extensions) and subfolders. I want to keep certain file extensions and delete the rest.



      e.g. keep all .txt and .jpg files and delete all other files.


      on regular UNIX/GNU, I can use find together with the "-not" parameter to achieve this.



      > find . -not -name "*.jpg" -not -name "*txt" -type f -delete


      But sadly, this parameter is not available on busybox find.



      Any ideas on how it can be done? Thanks a lot







      find busybox






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 14 '16 at 10:19









      mrjayviper

      475617




      475617




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          -not and -delete are non-standard extensions.



          There's no reason why you'd want to use -not, when there's a shorter standard equivalent: !.



          For -delete, you'll have to invoke rm with the -exec predicate:



          find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          (if you have an older version of busybox, you may need the -exec rm -f '' ';' which runs one rm per file).



          That command above is standard, so will work not only in busybox but also with other non-GNU modern implementations of find.



          Note that on GNU systems at least, that command (with any find implementation as long as it uses GNU fnmatch(3)) may still remove some files whose name ends in .jpg or .txt, as the *.jpg pattern would fail to match files whose name contains invalid characters in the current locale.



          To work around that, you'd need:



          LC_ALL=C find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          Also note that contrary to GNU's -delete, that approach won't work in very deep directory trees as you would then end up reaching the maximum size of a file path passed to the unlink() system call. AFAIK, with find, there's no way around that if your find implementation doesn't support -execdir nor -delete.



          You may also want to read the security considerations discussed in the GNU find manual if you're going to run that command in a directory writable by others.






          share|improve this answer






















          • I'm eager to find out wheter OP's version of find supports !. I kind of assumed it's not since -not was not supported.
            – Dmitry Grigoryev
            Mar 14 '16 at 11:53






          • 1




            @DmitryGrigoryev, hardly any find implementation supports -not (an extension added to GNU find in 2.0 in 1990, sometimes added later to other implementations like FreeBSD in 2002 for compatibility with GNU find). They all support ! though and have had since the very first version of Unix in 1970.
            – Stéphane Chazelas
            Mar 14 '16 at 12:25






          • 1




            @DmitryGrigoryev (continued) what the OP's find might miss is support for -exec + which was added recently to busybox find.
            – Stéphane Chazelas
            Mar 14 '16 at 12:27










          • @DmitryGrigoryev, actually the early Unix find implementations didn't take any option, all the -name, !... were added later on in the 70s.
            – Stéphane Chazelas
            Mar 14 '16 at 12:43










          • It should have been hard to use it then, considering one couldn't post-process the output.
            – Dmitry Grigoryev
            Mar 14 '16 at 13:17

















          up vote
          1
          down vote













          Busybox find claims to support -regex option, which you could use to remove files which do match the pattern:



          find . -type f -regex '.*.tmp|.*.core' -delete


          Unfortunately, excluding a list of extensions without the -not option is not possible in the general case (technically, there is a solution, but it doesn't scale). That's the reason to include the -not option in the first place. If you need to exclude an arbitrary list of extensions, you'll need a find which supports this option, or find+grep+xargs:



          find . | grep -v -e '.jpg$' -e '.txt$' | xargs rm





          share|improve this answer


















          • 1




            You can't post-process the output of find . unless you can make some assumptions on what characters the filename may contain. It's even worse when piping to xargs as in addition to newline, you'd also have problems with blanks, quotes and backslashes.
            – Stéphane Chazelas
            Mar 14 '16 at 11:52










          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%2f269645%2fhow-to-delete-or-keep-certain-file-extensions-using-busybox-find%23new-answer', 'question_page');

          );

          Post as a guest






























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote



          accepted










          -not and -delete are non-standard extensions.



          There's no reason why you'd want to use -not, when there's a shorter standard equivalent: !.



          For -delete, you'll have to invoke rm with the -exec predicate:



          find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          (if you have an older version of busybox, you may need the -exec rm -f '' ';' which runs one rm per file).



          That command above is standard, so will work not only in busybox but also with other non-GNU modern implementations of find.



          Note that on GNU systems at least, that command (with any find implementation as long as it uses GNU fnmatch(3)) may still remove some files whose name ends in .jpg or .txt, as the *.jpg pattern would fail to match files whose name contains invalid characters in the current locale.



          To work around that, you'd need:



          LC_ALL=C find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          Also note that contrary to GNU's -delete, that approach won't work in very deep directory trees as you would then end up reaching the maximum size of a file path passed to the unlink() system call. AFAIK, with find, there's no way around that if your find implementation doesn't support -execdir nor -delete.



          You may also want to read the security considerations discussed in the GNU find manual if you're going to run that command in a directory writable by others.






          share|improve this answer






















          • I'm eager to find out wheter OP's version of find supports !. I kind of assumed it's not since -not was not supported.
            – Dmitry Grigoryev
            Mar 14 '16 at 11:53






          • 1




            @DmitryGrigoryev, hardly any find implementation supports -not (an extension added to GNU find in 2.0 in 1990, sometimes added later to other implementations like FreeBSD in 2002 for compatibility with GNU find). They all support ! though and have had since the very first version of Unix in 1970.
            – Stéphane Chazelas
            Mar 14 '16 at 12:25






          • 1




            @DmitryGrigoryev (continued) what the OP's find might miss is support for -exec + which was added recently to busybox find.
            – Stéphane Chazelas
            Mar 14 '16 at 12:27










          • @DmitryGrigoryev, actually the early Unix find implementations didn't take any option, all the -name, !... were added later on in the 70s.
            – Stéphane Chazelas
            Mar 14 '16 at 12:43










          • It should have been hard to use it then, considering one couldn't post-process the output.
            – Dmitry Grigoryev
            Mar 14 '16 at 13:17














          up vote
          4
          down vote



          accepted










          -not and -delete are non-standard extensions.



          There's no reason why you'd want to use -not, when there's a shorter standard equivalent: !.



          For -delete, you'll have to invoke rm with the -exec predicate:



          find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          (if you have an older version of busybox, you may need the -exec rm -f '' ';' which runs one rm per file).



          That command above is standard, so will work not only in busybox but also with other non-GNU modern implementations of find.



          Note that on GNU systems at least, that command (with any find implementation as long as it uses GNU fnmatch(3)) may still remove some files whose name ends in .jpg or .txt, as the *.jpg pattern would fail to match files whose name contains invalid characters in the current locale.



          To work around that, you'd need:



          LC_ALL=C find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          Also note that contrary to GNU's -delete, that approach won't work in very deep directory trees as you would then end up reaching the maximum size of a file path passed to the unlink() system call. AFAIK, with find, there's no way around that if your find implementation doesn't support -execdir nor -delete.



          You may also want to read the security considerations discussed in the GNU find manual if you're going to run that command in a directory writable by others.






          share|improve this answer






















          • I'm eager to find out wheter OP's version of find supports !. I kind of assumed it's not since -not was not supported.
            – Dmitry Grigoryev
            Mar 14 '16 at 11:53






          • 1




            @DmitryGrigoryev, hardly any find implementation supports -not (an extension added to GNU find in 2.0 in 1990, sometimes added later to other implementations like FreeBSD in 2002 for compatibility with GNU find). They all support ! though and have had since the very first version of Unix in 1970.
            – Stéphane Chazelas
            Mar 14 '16 at 12:25






          • 1




            @DmitryGrigoryev (continued) what the OP's find might miss is support for -exec + which was added recently to busybox find.
            – Stéphane Chazelas
            Mar 14 '16 at 12:27










          • @DmitryGrigoryev, actually the early Unix find implementations didn't take any option, all the -name, !... were added later on in the 70s.
            – Stéphane Chazelas
            Mar 14 '16 at 12:43










          • It should have been hard to use it then, considering one couldn't post-process the output.
            – Dmitry Grigoryev
            Mar 14 '16 at 13:17












          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          -not and -delete are non-standard extensions.



          There's no reason why you'd want to use -not, when there's a shorter standard equivalent: !.



          For -delete, you'll have to invoke rm with the -exec predicate:



          find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          (if you have an older version of busybox, you may need the -exec rm -f '' ';' which runs one rm per file).



          That command above is standard, so will work not only in busybox but also with other non-GNU modern implementations of find.



          Note that on GNU systems at least, that command (with any find implementation as long as it uses GNU fnmatch(3)) may still remove some files whose name ends in .jpg or .txt, as the *.jpg pattern would fail to match files whose name contains invalid characters in the current locale.



          To work around that, you'd need:



          LC_ALL=C find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          Also note that contrary to GNU's -delete, that approach won't work in very deep directory trees as you would then end up reaching the maximum size of a file path passed to the unlink() system call. AFAIK, with find, there's no way around that if your find implementation doesn't support -execdir nor -delete.



          You may also want to read the security considerations discussed in the GNU find manual if you're going to run that command in a directory writable by others.






          share|improve this answer














          -not and -delete are non-standard extensions.



          There's no reason why you'd want to use -not, when there's a shorter standard equivalent: !.



          For -delete, you'll have to invoke rm with the -exec predicate:



          find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          (if you have an older version of busybox, you may need the -exec rm -f '' ';' which runs one rm per file).



          That command above is standard, so will work not only in busybox but also with other non-GNU modern implementations of find.



          Note that on GNU systems at least, that command (with any find implementation as long as it uses GNU fnmatch(3)) may still remove some files whose name ends in .jpg or .txt, as the *.jpg pattern would fail to match files whose name contains invalid characters in the current locale.



          To work around that, you'd need:



          LC_ALL=C find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '' +


          Also note that contrary to GNU's -delete, that approach won't work in very deep directory trees as you would then end up reaching the maximum size of a file path passed to the unlink() system call. AFAIK, with find, there's no way around that if your find implementation doesn't support -execdir nor -delete.



          You may also want to read the security considerations discussed in the GNU find manual if you're going to run that command in a directory writable by others.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 7 hours ago

























          answered Mar 14 '16 at 11:38









          Stéphane Chazelas

          292k54546886




          292k54546886











          • I'm eager to find out wheter OP's version of find supports !. I kind of assumed it's not since -not was not supported.
            – Dmitry Grigoryev
            Mar 14 '16 at 11:53






          • 1




            @DmitryGrigoryev, hardly any find implementation supports -not (an extension added to GNU find in 2.0 in 1990, sometimes added later to other implementations like FreeBSD in 2002 for compatibility with GNU find). They all support ! though and have had since the very first version of Unix in 1970.
            – Stéphane Chazelas
            Mar 14 '16 at 12:25






          • 1




            @DmitryGrigoryev (continued) what the OP's find might miss is support for -exec + which was added recently to busybox find.
            – Stéphane Chazelas
            Mar 14 '16 at 12:27










          • @DmitryGrigoryev, actually the early Unix find implementations didn't take any option, all the -name, !... were added later on in the 70s.
            – Stéphane Chazelas
            Mar 14 '16 at 12:43










          • It should have been hard to use it then, considering one couldn't post-process the output.
            – Dmitry Grigoryev
            Mar 14 '16 at 13:17
















          • I'm eager to find out wheter OP's version of find supports !. I kind of assumed it's not since -not was not supported.
            – Dmitry Grigoryev
            Mar 14 '16 at 11:53






          • 1




            @DmitryGrigoryev, hardly any find implementation supports -not (an extension added to GNU find in 2.0 in 1990, sometimes added later to other implementations like FreeBSD in 2002 for compatibility with GNU find). They all support ! though and have had since the very first version of Unix in 1970.
            – Stéphane Chazelas
            Mar 14 '16 at 12:25






          • 1




            @DmitryGrigoryev (continued) what the OP's find might miss is support for -exec + which was added recently to busybox find.
            – Stéphane Chazelas
            Mar 14 '16 at 12:27










          • @DmitryGrigoryev, actually the early Unix find implementations didn't take any option, all the -name, !... were added later on in the 70s.
            – Stéphane Chazelas
            Mar 14 '16 at 12:43










          • It should have been hard to use it then, considering one couldn't post-process the output.
            – Dmitry Grigoryev
            Mar 14 '16 at 13:17















          I'm eager to find out wheter OP's version of find supports !. I kind of assumed it's not since -not was not supported.
          – Dmitry Grigoryev
          Mar 14 '16 at 11:53




          I'm eager to find out wheter OP's version of find supports !. I kind of assumed it's not since -not was not supported.
          – Dmitry Grigoryev
          Mar 14 '16 at 11:53




          1




          1




          @DmitryGrigoryev, hardly any find implementation supports -not (an extension added to GNU find in 2.0 in 1990, sometimes added later to other implementations like FreeBSD in 2002 for compatibility with GNU find). They all support ! though and have had since the very first version of Unix in 1970.
          – Stéphane Chazelas
          Mar 14 '16 at 12:25




          @DmitryGrigoryev, hardly any find implementation supports -not (an extension added to GNU find in 2.0 in 1990, sometimes added later to other implementations like FreeBSD in 2002 for compatibility with GNU find). They all support ! though and have had since the very first version of Unix in 1970.
          – Stéphane Chazelas
          Mar 14 '16 at 12:25




          1




          1




          @DmitryGrigoryev (continued) what the OP's find might miss is support for -exec + which was added recently to busybox find.
          – Stéphane Chazelas
          Mar 14 '16 at 12:27




          @DmitryGrigoryev (continued) what the OP's find might miss is support for -exec + which was added recently to busybox find.
          – Stéphane Chazelas
          Mar 14 '16 at 12:27












          @DmitryGrigoryev, actually the early Unix find implementations didn't take any option, all the -name, !... were added later on in the 70s.
          – Stéphane Chazelas
          Mar 14 '16 at 12:43




          @DmitryGrigoryev, actually the early Unix find implementations didn't take any option, all the -name, !... were added later on in the 70s.
          – Stéphane Chazelas
          Mar 14 '16 at 12:43












          It should have been hard to use it then, considering one couldn't post-process the output.
          – Dmitry Grigoryev
          Mar 14 '16 at 13:17




          It should have been hard to use it then, considering one couldn't post-process the output.
          – Dmitry Grigoryev
          Mar 14 '16 at 13:17












          up vote
          1
          down vote













          Busybox find claims to support -regex option, which you could use to remove files which do match the pattern:



          find . -type f -regex '.*.tmp|.*.core' -delete


          Unfortunately, excluding a list of extensions without the -not option is not possible in the general case (technically, there is a solution, but it doesn't scale). That's the reason to include the -not option in the first place. If you need to exclude an arbitrary list of extensions, you'll need a find which supports this option, or find+grep+xargs:



          find . | grep -v -e '.jpg$' -e '.txt$' | xargs rm





          share|improve this answer


















          • 1




            You can't post-process the output of find . unless you can make some assumptions on what characters the filename may contain. It's even worse when piping to xargs as in addition to newline, you'd also have problems with blanks, quotes and backslashes.
            – Stéphane Chazelas
            Mar 14 '16 at 11:52














          up vote
          1
          down vote













          Busybox find claims to support -regex option, which you could use to remove files which do match the pattern:



          find . -type f -regex '.*.tmp|.*.core' -delete


          Unfortunately, excluding a list of extensions without the -not option is not possible in the general case (technically, there is a solution, but it doesn't scale). That's the reason to include the -not option in the first place. If you need to exclude an arbitrary list of extensions, you'll need a find which supports this option, or find+grep+xargs:



          find . | grep -v -e '.jpg$' -e '.txt$' | xargs rm





          share|improve this answer


















          • 1




            You can't post-process the output of find . unless you can make some assumptions on what characters the filename may contain. It's even worse when piping to xargs as in addition to newline, you'd also have problems with blanks, quotes and backslashes.
            – Stéphane Chazelas
            Mar 14 '16 at 11:52












          up vote
          1
          down vote










          up vote
          1
          down vote









          Busybox find claims to support -regex option, which you could use to remove files which do match the pattern:



          find . -type f -regex '.*.tmp|.*.core' -delete


          Unfortunately, excluding a list of extensions without the -not option is not possible in the general case (technically, there is a solution, but it doesn't scale). That's the reason to include the -not option in the first place. If you need to exclude an arbitrary list of extensions, you'll need a find which supports this option, or find+grep+xargs:



          find . | grep -v -e '.jpg$' -e '.txt$' | xargs rm





          share|improve this answer














          Busybox find claims to support -regex option, which you could use to remove files which do match the pattern:



          find . -type f -regex '.*.tmp|.*.core' -delete


          Unfortunately, excluding a list of extensions without the -not option is not possible in the general case (technically, there is a solution, but it doesn't scale). That's the reason to include the -not option in the first place. If you need to exclude an arbitrary list of extensions, you'll need a find which supports this option, or find+grep+xargs:



          find . | grep -v -e '.jpg$' -e '.txt$' | xargs rm






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 23 '17 at 12:40









          Community

          1




          1










          answered Mar 14 '16 at 11:22









          Dmitry Grigoryev

          5,034744




          5,034744







          • 1




            You can't post-process the output of find . unless you can make some assumptions on what characters the filename may contain. It's even worse when piping to xargs as in addition to newline, you'd also have problems with blanks, quotes and backslashes.
            – Stéphane Chazelas
            Mar 14 '16 at 11:52












          • 1




            You can't post-process the output of find . unless you can make some assumptions on what characters the filename may contain. It's even worse when piping to xargs as in addition to newline, you'd also have problems with blanks, quotes and backslashes.
            – Stéphane Chazelas
            Mar 14 '16 at 11:52







          1




          1




          You can't post-process the output of find . unless you can make some assumptions on what characters the filename may contain. It's even worse when piping to xargs as in addition to newline, you'd also have problems with blanks, quotes and backslashes.
          – Stéphane Chazelas
          Mar 14 '16 at 11:52




          You can't post-process the output of find . unless you can make some assumptions on what characters the filename may contain. It's even worse when piping to xargs as in addition to newline, you'd also have problems with blanks, quotes and backslashes.
          – Stéphane Chazelas
          Mar 14 '16 at 11:52

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f269645%2fhow-to-delete-or-keep-certain-file-extensions-using-busybox-find%23new-answer', 'question_page');

          );

          Post as a guest













































































          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?