5

I have a directory with a bunch of files extensions mixed and I would like to list a specific file extension (maybe something like grep *.mp3) and while listing, delete them with an output. How can I do that or if there's a dupe, please feel free to tag me in.

Example:

grep "*.mp3" . | rm -fr 
5

Let's start with a directory with three mp3 files:

$ ls *mp3
a.mp3  b.mp3  c.mp3

Now, let's delete them after we list what we are deleting:

$ find . -maxdepth 1 -name '*.mp3' -printf 'Deleting %p\n' -delete
Deleting ./a.mp3
Deleting ./b.mp3
Deleting ./c.mp3

After this is done, the mp3 files are gone:

$ ls *mp3
ls: cannot access '*mp3': No such file or directory

How it works

  • `find .

    This starts a find command. It will look for files in the current directory, ..

  • -maxdepth 1

    By default, find recursively searches subdirectories. This tells it not to do that. With -maxdepth 1, the command find will only look at what it finds in the current directory and not explore any of the current directory's subdirectories.

  • -name '*.mp3'

    This tells find to look only for files with the .mp3 extension.

  • -printf 'Deleting %p\n'

    This tells find to print a message about each file found.

    You can, of course, change this to another message if you like. If you don't want a message, then this option can be omitted entirely.

  • -delete

    This tells find to delete each file.

Case insensitive search

If you also want to find files named .MP3 or .Mp3 etc., then we need a case-insensitive search and we use -iname:

find . -maxdepth 1 -iname '*.mp3' -printf 'Deleting %p\n' -delete
  • -iname seems better because there are MP3 files that end in .MP3. – edwinksl Sep 24 '16 at 5:50
  • @edwinksl OK. I added that to the answer. – John1024 Sep 24 '16 at 5:53
  • Thanks for the heads up! worked perfectly... I though of the find command but no sure why I haven't gone this route. BTW, I'm pretty confused about -maxdepth 1 on This tells it not to.h 1. I'm lost at and would you mind repeating the explanation a bit, please. – AzkerM Sep 24 '16 at 7:19
  • Okay! I figured out looking the other user's answer. Thank you BTW. – AzkerM Sep 24 '16 at 7:21
  • @AzkerM Oops: something went wrong with my editing there! Answer updated. Glad you figured it figured out anyway. – John1024 Sep 24 '16 at 7:49
4

You want find...

find . -type f -iname "*.mp3"

By default it will recurse to subdirectories, so if you are getting more files than you want, add -maxdepth 1 to search in the current directory only. After checking that the output is what you want to delete, you can do it again (thank you up-arrow...) and add -delete.

find . -type f -iname "*.mp3" -delete

. is the current working directory - you can give the path to the directory here instead if you are not in it...

To make it interactive, you could use -exec to define your own action instead of find's -delete action

find . -type f -iname "*.mp3" -exec rm -i -- {} \;

Then it will prompt you before deleting each file...

  • Thank you for your explanation too. Now I understood why -maxdepth 1 is used. This is to pretty much stay in the current directory. ^_^ – AzkerM Sep 24 '16 at 7:21
  • yes @AzkerM or to stay in the directory specified (you could give a path instead of the current dir like find ~/Downloads -maxdepth 1 -type f -iname "*.mp3") and not go into any subdirectories :) – Zanna Sep 24 '16 at 7:23
  • Yes, specifying the directory path is pretty clear to me but the -maxdepth 1 actually made sense to me now. You're good at explaining and Kudos to that :) – AzkerM Sep 24 '16 at 7:27
  • :D thanks @AzkerM & thanks for the nice question – Zanna Sep 24 '16 at 7:28
  • Well, it was a stupid question I know but the explaining makes it understand more on what we actually do. That's what matters to me most than typing a bunch of commands... :D – AzkerM Sep 24 '16 at 7:28
3

When you want to delete only items in current directory, it is sufficient to use the wildcard like so:

$ ls *.jpeg
birthday2016_001.jpeg  birthday2016_002.jpeg  birthday2016_003.jpeg
$ rm *.jpeg
$ ls *.jpeg
ls: cannot access '*.jpeg': No such file or directory

As you can see, in the example above, all files with .jpeg extension got removed. Listing them , is the same idea - echo *.jpeg and ls *.jpeg. So you essentially could do simply ls *.mp3 && rm *.mp3 for your case

Python alternative:

In my case, I was removing .jpeg file, so adjust the code below as necessary:

 python -c 'import os,sys;[(sys.stdout.write(i + "\n"),os.unlink(i)) for i in os.listdir(".")  if i.endswith(".jpeg")]'

Sample run:

$ ls *.jpeg
birthday2016_001.jpeg  birthday2016_002.jpeg  birthday2016_003.jpeg     
$ python -c 'import os,sys;[(sys.stdout.write(i + "\n"),os.unlink(i)) for i in os.listdir(".")  if i.endswith(".jpeg")]'
birthday2016_003.jpeg
birthday2016_001.jpeg
birthday2016_002.jpeg
$ ls *.jpeg
ls: cannot access '*.jpeg': No such file or directory
  • 1
    Thank you for simplifying it. ls *.mp3 && rm *.mp3 actually make sense.. didn't think of this way at all.. Also, thank you for the python alternative, I should get myself a little knowledge on python.. :) – AzkerM Sep 25 '16 at 6:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.