How do I delete files of certain extension that don't have a given string in their filename?

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











up vote
6
down vote

favorite












I have a directory with files of many extensions in it. I would like to recursively delete *.srt files (and *.srt files only) which don't end with -en.srt (where srt is an extension). I've come up with the following solution and it seems to work fine, however, I'd like to know whether it is 100% correct.



find . -name "*.srt" ! -name "*-en.srt" -type f -exec rm -rf ;









share|improve this question



























    up vote
    6
    down vote

    favorite












    I have a directory with files of many extensions in it. I would like to recursively delete *.srt files (and *.srt files only) which don't end with -en.srt (where srt is an extension). I've come up with the following solution and it seems to work fine, however, I'd like to know whether it is 100% correct.



    find . -name "*.srt" ! -name "*-en.srt" -type f -exec rm -rf ;









    share|improve this question

























      up vote
      6
      down vote

      favorite









      up vote
      6
      down vote

      favorite











      I have a directory with files of many extensions in it. I would like to recursively delete *.srt files (and *.srt files only) which don't end with -en.srt (where srt is an extension). I've come up with the following solution and it seems to work fine, however, I'd like to know whether it is 100% correct.



      find . -name "*.srt" ! -name "*-en.srt" -type f -exec rm -rf ;









      share|improve this question















      I have a directory with files of many extensions in it. I would like to recursively delete *.srt files (and *.srt files only) which don't end with -en.srt (where srt is an extension). I've come up with the following solution and it seems to work fine, however, I'd like to know whether it is 100% correct.



      find . -name "*.srt" ! -name "*-en.srt" -type f -exec rm -rf ;






      command-line rm






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 13 at 18:30

























      asked Aug 11 at 13:26









      menteith

      1768




      1768




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          8
          down vote



          accepted










          ! -- First read the answer completely then use it if you like it -- !



          Your command is correct, however there is no need to use -rf as rm parameters. because you are removing files and not directories.



          Another clear way to write it is (it's almost same as your command):



          find -name '*.srt' -and -not -name '*-en.srt' -type f -exec rm '' ;


          or as @steeldriver suggested you can use:



          find -name '*.srt' -and -not -name '*-en.srt' -type f -ok rm '' ;


          It will ask for your permission to remove each founded file.



          You can also use -delete instead of rm ; however be aware of its dangers:




          Don't forget that the find command line is evaluated as an expres‐
          sion, so putting -delete first will make find try to delete everything below
          the starting points you specified. When testing a find command line that you
          later intend to use with -delete, you should explicitly specify -depth in order
          to avoid later surprises. Because -delete implies -depth, you cannot usefully
          use -prune and -delete together.





          It is always a good idea to test what is going to happen before doing the actual job, so I suggest running:



          find -name '*.srt' -and -not -name '*-en.srt' -type f | grep -i en.srt


          If it return nothing then the actual command will work without any problem and you are good to go... or even:



          find -name '*.srt' -and -not -name '*-en.srt' -type f | less


          to check what's going to be removed.



          And do not forget to quote '':




          (when find is being invoked from a shell)
          it should be quoted (for example, '') to protect it from interpretation by shells.







          share|improve this answer






















          • How about -en.srt in my original command? Is it going ot be found in any place in the filename or only at the end?
            – menteith
            Aug 11 at 14:08










          • @menteith At the end of file name...
            – Ravexina
            Aug 11 at 14:11






          • 1




            +1 for mentioning that -rf is not needed. The part -exec rm ; can be improved by writing -exec rm + instead. This way rm will be called with as many files as fit into the command line, effectively speeding up the whole process a lot when there are many files.
            – PerlDuck
            Aug 11 at 14:45







          • 2




            +1 for sharing a "good idea". Is it advisable to single quote the curly brackets ('') to prevent the shell from expanding strange filenames?
            – mook765
            Aug 11 at 15:27







          • 1




            @dessert, -delete usage has been suggested in answer... and about -name option you are right` it's my bad habit to always use -iname instead of -name... will update it.
            – Ravexina
            Aug 12 at 7:45


















          up vote
          4
          down vote















          Let’s do it solely with bash globbing: With the extglob and globstar options enabled,



          rm **/!(*-en).srt


          deletes every file ending in .srt excluding anything ending in -en.srt from the current as well as any subdirectory.

          If you‘re not sure about an expansion like this, test by prepending echo (see example below).



          Example



          $ tree
          .
          ├── 01.srt
          ├── 02.srt
          ├── no-en.srt
          ├── not-en.srt
          ├── subdir
          │   ├── 01.srt
          │   ├── 02.srt
          │   ├── no-en.srt
          │   └── not-en.srt
          └── unrelated.png
          $ shopt -s extglob globstar
          $ echo rm **/!(*-en).srt
          rm 01.srt 02.srt subdir/01.srt subdir/02.srt
          $ rm **/!(*-en).srt
          $ tree
          .
          ├── no-en.srt
          ├── not-en.srt
          ├── subdir
          │   ├── no-en.srt
          │   └── not-en.srt
          └── unrelated.png


          Explanations




          • **/ – with the globstar option enabled this matches any number of directories and subdirectories


          • !(*-en) – with the extglob option enabled this matches anything except the given pattern, so anything not ending in -en





          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',
            convertImagesToLinks: true,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            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%2f1064419%2fhow-do-i-delete-files-of-certain-extension-that-dont-have-a-given-string-in-the%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
            8
            down vote



            accepted










            ! -- First read the answer completely then use it if you like it -- !



            Your command is correct, however there is no need to use -rf as rm parameters. because you are removing files and not directories.



            Another clear way to write it is (it's almost same as your command):



            find -name '*.srt' -and -not -name '*-en.srt' -type f -exec rm '' ;


            or as @steeldriver suggested you can use:



            find -name '*.srt' -and -not -name '*-en.srt' -type f -ok rm '' ;


            It will ask for your permission to remove each founded file.



            You can also use -delete instead of rm ; however be aware of its dangers:




            Don't forget that the find command line is evaluated as an expres‐
            sion, so putting -delete first will make find try to delete everything below
            the starting points you specified. When testing a find command line that you
            later intend to use with -delete, you should explicitly specify -depth in order
            to avoid later surprises. Because -delete implies -depth, you cannot usefully
            use -prune and -delete together.





            It is always a good idea to test what is going to happen before doing the actual job, so I suggest running:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | grep -i en.srt


            If it return nothing then the actual command will work without any problem and you are good to go... or even:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | less


            to check what's going to be removed.



            And do not forget to quote '':




            (when find is being invoked from a shell)
            it should be quoted (for example, '') to protect it from interpretation by shells.







            share|improve this answer






















            • How about -en.srt in my original command? Is it going ot be found in any place in the filename or only at the end?
              – menteith
              Aug 11 at 14:08










            • @menteith At the end of file name...
              – Ravexina
              Aug 11 at 14:11






            • 1




              +1 for mentioning that -rf is not needed. The part -exec rm ; can be improved by writing -exec rm + instead. This way rm will be called with as many files as fit into the command line, effectively speeding up the whole process a lot when there are many files.
              – PerlDuck
              Aug 11 at 14:45







            • 2




              +1 for sharing a "good idea". Is it advisable to single quote the curly brackets ('') to prevent the shell from expanding strange filenames?
              – mook765
              Aug 11 at 15:27







            • 1




              @dessert, -delete usage has been suggested in answer... and about -name option you are right` it's my bad habit to always use -iname instead of -name... will update it.
              – Ravexina
              Aug 12 at 7:45















            up vote
            8
            down vote



            accepted










            ! -- First read the answer completely then use it if you like it -- !



            Your command is correct, however there is no need to use -rf as rm parameters. because you are removing files and not directories.



            Another clear way to write it is (it's almost same as your command):



            find -name '*.srt' -and -not -name '*-en.srt' -type f -exec rm '' ;


            or as @steeldriver suggested you can use:



            find -name '*.srt' -and -not -name '*-en.srt' -type f -ok rm '' ;


            It will ask for your permission to remove each founded file.



            You can also use -delete instead of rm ; however be aware of its dangers:




            Don't forget that the find command line is evaluated as an expres‐
            sion, so putting -delete first will make find try to delete everything below
            the starting points you specified. When testing a find command line that you
            later intend to use with -delete, you should explicitly specify -depth in order
            to avoid later surprises. Because -delete implies -depth, you cannot usefully
            use -prune and -delete together.





            It is always a good idea to test what is going to happen before doing the actual job, so I suggest running:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | grep -i en.srt


            If it return nothing then the actual command will work without any problem and you are good to go... or even:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | less


            to check what's going to be removed.



            And do not forget to quote '':




            (when find is being invoked from a shell)
            it should be quoted (for example, '') to protect it from interpretation by shells.







            share|improve this answer






















            • How about -en.srt in my original command? Is it going ot be found in any place in the filename or only at the end?
              – menteith
              Aug 11 at 14:08










            • @menteith At the end of file name...
              – Ravexina
              Aug 11 at 14:11






            • 1




              +1 for mentioning that -rf is not needed. The part -exec rm ; can be improved by writing -exec rm + instead. This way rm will be called with as many files as fit into the command line, effectively speeding up the whole process a lot when there are many files.
              – PerlDuck
              Aug 11 at 14:45







            • 2




              +1 for sharing a "good idea". Is it advisable to single quote the curly brackets ('') to prevent the shell from expanding strange filenames?
              – mook765
              Aug 11 at 15:27







            • 1




              @dessert, -delete usage has been suggested in answer... and about -name option you are right` it's my bad habit to always use -iname instead of -name... will update it.
              – Ravexina
              Aug 12 at 7:45













            up vote
            8
            down vote



            accepted







            up vote
            8
            down vote



            accepted






            ! -- First read the answer completely then use it if you like it -- !



            Your command is correct, however there is no need to use -rf as rm parameters. because you are removing files and not directories.



            Another clear way to write it is (it's almost same as your command):



            find -name '*.srt' -and -not -name '*-en.srt' -type f -exec rm '' ;


            or as @steeldriver suggested you can use:



            find -name '*.srt' -and -not -name '*-en.srt' -type f -ok rm '' ;


            It will ask for your permission to remove each founded file.



            You can also use -delete instead of rm ; however be aware of its dangers:




            Don't forget that the find command line is evaluated as an expres‐
            sion, so putting -delete first will make find try to delete everything below
            the starting points you specified. When testing a find command line that you
            later intend to use with -delete, you should explicitly specify -depth in order
            to avoid later surprises. Because -delete implies -depth, you cannot usefully
            use -prune and -delete together.





            It is always a good idea to test what is going to happen before doing the actual job, so I suggest running:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | grep -i en.srt


            If it return nothing then the actual command will work without any problem and you are good to go... or even:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | less


            to check what's going to be removed.



            And do not forget to quote '':




            (when find is being invoked from a shell)
            it should be quoted (for example, '') to protect it from interpretation by shells.







            share|improve this answer














            ! -- First read the answer completely then use it if you like it -- !



            Your command is correct, however there is no need to use -rf as rm parameters. because you are removing files and not directories.



            Another clear way to write it is (it's almost same as your command):



            find -name '*.srt' -and -not -name '*-en.srt' -type f -exec rm '' ;


            or as @steeldriver suggested you can use:



            find -name '*.srt' -and -not -name '*-en.srt' -type f -ok rm '' ;


            It will ask for your permission to remove each founded file.



            You can also use -delete instead of rm ; however be aware of its dangers:




            Don't forget that the find command line is evaluated as an expres‐
            sion, so putting -delete first will make find try to delete everything below
            the starting points you specified. When testing a find command line that you
            later intend to use with -delete, you should explicitly specify -depth in order
            to avoid later surprises. Because -delete implies -depth, you cannot usefully
            use -prune and -delete together.





            It is always a good idea to test what is going to happen before doing the actual job, so I suggest running:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | grep -i en.srt


            If it return nothing then the actual command will work without any problem and you are good to go... or even:



            find -name '*.srt' -and -not -name '*-en.srt' -type f | less


            to check what's going to be removed.



            And do not forget to quote '':




            (when find is being invoked from a shell)
            it should be quoted (for example, '') to protect it from interpretation by shells.








            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Aug 12 at 7:45

























            answered Aug 11 at 13:59









            Ravexina

            27.9k146595




            27.9k146595











            • How about -en.srt in my original command? Is it going ot be found in any place in the filename or only at the end?
              – menteith
              Aug 11 at 14:08










            • @menteith At the end of file name...
              – Ravexina
              Aug 11 at 14:11






            • 1




              +1 for mentioning that -rf is not needed. The part -exec rm ; can be improved by writing -exec rm + instead. This way rm will be called with as many files as fit into the command line, effectively speeding up the whole process a lot when there are many files.
              – PerlDuck
              Aug 11 at 14:45







            • 2




              +1 for sharing a "good idea". Is it advisable to single quote the curly brackets ('') to prevent the shell from expanding strange filenames?
              – mook765
              Aug 11 at 15:27







            • 1




              @dessert, -delete usage has been suggested in answer... and about -name option you are right` it's my bad habit to always use -iname instead of -name... will update it.
              – Ravexina
              Aug 12 at 7:45

















            • How about -en.srt in my original command? Is it going ot be found in any place in the filename or only at the end?
              – menteith
              Aug 11 at 14:08










            • @menteith At the end of file name...
              – Ravexina
              Aug 11 at 14:11






            • 1




              +1 for mentioning that -rf is not needed. The part -exec rm ; can be improved by writing -exec rm + instead. This way rm will be called with as many files as fit into the command line, effectively speeding up the whole process a lot when there are many files.
              – PerlDuck
              Aug 11 at 14:45







            • 2




              +1 for sharing a "good idea". Is it advisable to single quote the curly brackets ('') to prevent the shell from expanding strange filenames?
              – mook765
              Aug 11 at 15:27







            • 1




              @dessert, -delete usage has been suggested in answer... and about -name option you are right` it's my bad habit to always use -iname instead of -name... will update it.
              – Ravexina
              Aug 12 at 7:45
















            How about -en.srt in my original command? Is it going ot be found in any place in the filename or only at the end?
            – menteith
            Aug 11 at 14:08




            How about -en.srt in my original command? Is it going ot be found in any place in the filename or only at the end?
            – menteith
            Aug 11 at 14:08












            @menteith At the end of file name...
            – Ravexina
            Aug 11 at 14:11




            @menteith At the end of file name...
            – Ravexina
            Aug 11 at 14:11




            1




            1




            +1 for mentioning that -rf is not needed. The part -exec rm ; can be improved by writing -exec rm + instead. This way rm will be called with as many files as fit into the command line, effectively speeding up the whole process a lot when there are many files.
            – PerlDuck
            Aug 11 at 14:45





            +1 for mentioning that -rf is not needed. The part -exec rm ; can be improved by writing -exec rm + instead. This way rm will be called with as many files as fit into the command line, effectively speeding up the whole process a lot when there are many files.
            – PerlDuck
            Aug 11 at 14:45





            2




            2




            +1 for sharing a "good idea". Is it advisable to single quote the curly brackets ('') to prevent the shell from expanding strange filenames?
            – mook765
            Aug 11 at 15:27





            +1 for sharing a "good idea". Is it advisable to single quote the curly brackets ('') to prevent the shell from expanding strange filenames?
            – mook765
            Aug 11 at 15:27





            1




            1




            @dessert, -delete usage has been suggested in answer... and about -name option you are right` it's my bad habit to always use -iname instead of -name... will update it.
            – Ravexina
            Aug 12 at 7:45





            @dessert, -delete usage has been suggested in answer... and about -name option you are right` it's my bad habit to always use -iname instead of -name... will update it.
            – Ravexina
            Aug 12 at 7:45













            up vote
            4
            down vote















            Let’s do it solely with bash globbing: With the extglob and globstar options enabled,



            rm **/!(*-en).srt


            deletes every file ending in .srt excluding anything ending in -en.srt from the current as well as any subdirectory.

            If you‘re not sure about an expansion like this, test by prepending echo (see example below).



            Example



            $ tree
            .
            ├── 01.srt
            ├── 02.srt
            ├── no-en.srt
            ├── not-en.srt
            ├── subdir
            │   ├── 01.srt
            │   ├── 02.srt
            │   ├── no-en.srt
            │   └── not-en.srt
            └── unrelated.png
            $ shopt -s extglob globstar
            $ echo rm **/!(*-en).srt
            rm 01.srt 02.srt subdir/01.srt subdir/02.srt
            $ rm **/!(*-en).srt
            $ tree
            .
            ├── no-en.srt
            ├── not-en.srt
            ├── subdir
            │   ├── no-en.srt
            │   └── not-en.srt
            └── unrelated.png


            Explanations




            • **/ – with the globstar option enabled this matches any number of directories and subdirectories


            • !(*-en) – with the extglob option enabled this matches anything except the given pattern, so anything not ending in -en





            share|improve this answer
























              up vote
              4
              down vote















              Let’s do it solely with bash globbing: With the extglob and globstar options enabled,



              rm **/!(*-en).srt


              deletes every file ending in .srt excluding anything ending in -en.srt from the current as well as any subdirectory.

              If you‘re not sure about an expansion like this, test by prepending echo (see example below).



              Example



              $ tree
              .
              ├── 01.srt
              ├── 02.srt
              ├── no-en.srt
              ├── not-en.srt
              ├── subdir
              │   ├── 01.srt
              │   ├── 02.srt
              │   ├── no-en.srt
              │   └── not-en.srt
              └── unrelated.png
              $ shopt -s extglob globstar
              $ echo rm **/!(*-en).srt
              rm 01.srt 02.srt subdir/01.srt subdir/02.srt
              $ rm **/!(*-en).srt
              $ tree
              .
              ├── no-en.srt
              ├── not-en.srt
              ├── subdir
              │   ├── no-en.srt
              │   └── not-en.srt
              └── unrelated.png


              Explanations




              • **/ – with the globstar option enabled this matches any number of directories and subdirectories


              • !(*-en) – with the extglob option enabled this matches anything except the given pattern, so anything not ending in -en





              share|improve this answer






















                up vote
                4
                down vote










                up vote
                4
                down vote











                Let’s do it solely with bash globbing: With the extglob and globstar options enabled,



                rm **/!(*-en).srt


                deletes every file ending in .srt excluding anything ending in -en.srt from the current as well as any subdirectory.

                If you‘re not sure about an expansion like this, test by prepending echo (see example below).



                Example



                $ tree
                .
                ├── 01.srt
                ├── 02.srt
                ├── no-en.srt
                ├── not-en.srt
                ├── subdir
                │   ├── 01.srt
                │   ├── 02.srt
                │   ├── no-en.srt
                │   └── not-en.srt
                └── unrelated.png
                $ shopt -s extglob globstar
                $ echo rm **/!(*-en).srt
                rm 01.srt 02.srt subdir/01.srt subdir/02.srt
                $ rm **/!(*-en).srt
                $ tree
                .
                ├── no-en.srt
                ├── not-en.srt
                ├── subdir
                │   ├── no-en.srt
                │   └── not-en.srt
                └── unrelated.png


                Explanations




                • **/ – with the globstar option enabled this matches any number of directories and subdirectories


                • !(*-en) – with the extglob option enabled this matches anything except the given pattern, so anything not ending in -en





                share|improve this answer














                Let’s do it solely with bash globbing: With the extglob and globstar options enabled,



                rm **/!(*-en).srt


                deletes every file ending in .srt excluding anything ending in -en.srt from the current as well as any subdirectory.

                If you‘re not sure about an expansion like this, test by prepending echo (see example below).



                Example



                $ tree
                .
                ├── 01.srt
                ├── 02.srt
                ├── no-en.srt
                ├── not-en.srt
                ├── subdir
                │   ├── 01.srt
                │   ├── 02.srt
                │   ├── no-en.srt
                │   └── not-en.srt
                └── unrelated.png
                $ shopt -s extglob globstar
                $ echo rm **/!(*-en).srt
                rm 01.srt 02.srt subdir/01.srt subdir/02.srt
                $ rm **/!(*-en).srt
                $ tree
                .
                ├── no-en.srt
                ├── not-en.srt
                ├── subdir
                │   ├── no-en.srt
                │   └── not-en.srt
                └── unrelated.png


                Explanations




                • **/ – with the globstar option enabled this matches any number of directories and subdirectories


                • !(*-en) – with the extglob option enabled this matches anything except the given pattern, so anything not ending in -en






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Aug 12 at 7:34









                dessert

                19.8k55594




                19.8k55594



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1064419%2fhow-do-i-delete-files-of-certain-extension-that-dont-have-a-given-string-in-the%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?

                    Bahrain

                    Postfix configuration issue with fips on centos 7; mailgun relay