My ~/Music/ directory is actually full of "empty" directories I want to clean. I say "empty" because this directories actually contain files, some contain old cover image files or Thumbs.db files.

I want to recursively delete all of these directories that don't contain any music files inside or other directories inside.

For example ~/Music/Audioslave/ contains a lot of directories with album names and no music files, but I don't want to delete it because inside there are the music files. I want though to delete ~/Music/Audioslave/oldalbum/ if the oldalbum directory doesn't have nor music files nor other directories inside.

  • follow-up Q's: (1) Do you have only one folder with many other folders that contain files other than music files? (2) did you mean you have one folder, with folders that contain both folders and files where some folders carry music files and others do not?
    – slm
    Nov 1, 2013 at 21:58
  • See the solution I provided, it can handle the nested directories issue.
    – slm
    Nov 1, 2013 at 22:00
  • Your phrasing is still off (at least to me) I think what you're trying to say is you don't want to delete any directories that have mp3 files in them or contain nested directories that contain mp3 files, no?
    – slm
    Nov 1, 2013 at 22:04
  • that's exactly what I need, but also for .flac and .m4a!
    – volotec
    Nov 1, 2013 at 22:12
  • the answer I provided gives you this. I'll add those media types to it as well.
    – slm
    Nov 1, 2013 at 22:17

3 Answers 3


A funny solution involves a find inside a find, but in a safer way than the accepted answer (I personally dislike parsing the output of a command, being ls or find, especially with no precautions). The following command will print the folders that don't contain any music file (here, music file means has an extension mp3, flac, ogg, wav or m4a, but feel free to add some more):

find . -depth -type d \! -exec sh -c 'find "$1" \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.ogg" -o -iname "*.wav" -o -iname "*.m4a" \) -type f | read a' _ {} \; -print

You should try this on your system, when you're happy the way it behaves, replace the final -print with -exec rm -rfv -- {} \;

The way the file names are used here makes this method 100% safe regarding file names with funny symbols (i.e., spaces, quotings, newlines, trailing newlines, leading and trailing spaces, etc.).

  • @volotec - as I indicated in my answer it could be condensed, this is how.
    – slm
    Nov 1, 2013 at 23:35

I found this example on SO, titled: Terminal - Delete All Folders Not Conatining .mp3 Files.

#! /bin/bash

find -depth -type d | while read -r D
 v=$(find "$D" -iname '*.mp3')
 case "$v" in
 ""  )
    echo "$D no mp3"
    # rm -fr "$D" #uncomment to use


Sample data.

|-- 1
|   |-- 1.mp3
|   `-- 1.txt
|-- 2
|   `-- 2.mp3
|-- 3
|   `-- 3.txt
|-- 4
|   `-- 4.txt
|-- 5
|   `-- 5.mp3
|-- 6
|   `-- 61
|       `-- 61.mp3
|-- 7
|   `-- 71
|       `-- 71.txt
`-- deletenomp3.bash

Sample run

If I were to run it it would delete the following:

$ ./deletenomp3.bash 
./7 no mp3
./7/71 no mp3
./4 no mp3
./3 no mp3

Other file types

You can simply extend this by adding more -name arguments to the 2nd find command in the script. Example, to add .wav files:

 v=$(find "$D" -iname '*.mp3' -o -iname '*.wav');

That says *.mp3 OR *.wav. To add more or others:

 v=$(find "$D" -iname '*.mp3' -o -iname '*.flac' -o -iname '*.m4a');

I'm sure this block could be condensed if you had a lot more file types using alternative switching to find.

  • OK, it worked! Thanks a lot for your help. I wanted to give your answer points but since I'm new the system won't let me do it since I lack reputation points :(
    – volotec
    Nov 1, 2013 at 22:48
  • @volotec - you can mark it as the accepted answer 8-). Once you get over 15 points you can start to upvote.
    – slm
    Nov 1, 2013 at 22:49

Try something along the lines of this (untested):

for dir in ~/Music/* ; do
    # Add your music file extensions here.
    for file in "$dir"/*.{mp3,wav} */ ; do
        if ls "$file" > /dev/null 2>&1 ; then

    if ! $found ; then
        # Remove 'echo' when you are ready.
        echo rm -vrf "$dir"

I am not sure how many shells support the */ globbing. At least Bash and Zsh do.

  • 1
    The directories are not empty. What he really wants are directories that don't contain '*.mp3' or maybe '*.wav'.
    – jordanm
    Nov 1, 2013 at 21:34
  • Yes I know. Thing is the directories I want to remove contain certains files that are not music. For example Thumbs.db files. For that reason I can't use the -empty option for find
    – volotec
    Nov 1, 2013 at 21:34
  • I read the question too quickly and missed the main point. I will write a new answer.
    – user26112
    Nov 1, 2013 at 21:35
  • I have replaced my answer.
    – user26112
    Nov 1, 2013 at 21:40
  • Actually running your script made me realize my question was incomplete. I'm going to edit it, thanks!
    – volotec
    Nov 1, 2013 at 21:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .