Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

My harddrive is in a mess, so I decided to do a cleanup. As a part of this, I want to merge all folders containing music into one. What I want to do is, look for any *.mp3's and *.aac's on my drive and retrieve the name of the folders. Then, I want to remove any duplicate folder names and in a last step only grab the root directories. I find it hard to explain it accurately, so here's a picture of a sample tree:

  | ...contains photos and documents (no mp3/aac)...

For this example, my desired output is root1/folder1 root2/folder3 root2/folder4.

As I have only limited knowledge of bash and UNIX-tools, I have no idea how to do this. Is there a way to achieve this? I'm fine if your solution features find, but it would be much better if locate is used instead.

share|improve this question
Is there a reason you can't simply search for files ending in .mp3 with a GUI search tool and then sort by the folder the file is located in? Then simply move the files to where you wish. – David Mar 21 '13 at 21:29
If you use locate then please make sure your locatedb is up to date. Else it will miss some of the files you added after you updated it. (E.g add MP3s. updatedb. (noting the location of every mp3). Add more MP3s (which are not in the locate database yet!) – Hennes Mar 21 '13 at 23:12
@Jikag: That would destroy the structure of the subfolders, I want to keep it. – Max Beikirch Mar 22 '13 at 15:55
@Hennes: Thanks, I'll keep that in mind. – Max Beikirch Mar 22 '13 at 15:55
up vote 3 down vote accepted

Go into each of the final top-level folders, and move any .mp3 or .aac files beneath that folder to the present folder, then remove the now-empty folders, try:

for f in root*/folder*; do
    cd $f
    find -name "*mp3" -exec sh -c "mv {}  \$(basename {})" \;
    find -name "*aac" -exec sh -c "mv {}  \$(basename {})" \;
    find -type d -exec rmdir {} \;
    cd -

You will see errors about trying to rmdir non-empty folders, but the empty ones will be removed.

If you just want to know which top-level folders contain subfolders with mp3 or aac files:

find -name "*mp3" -o -name "*aac" | cut -d/ -f1-3 | sort -u

Find all .mp3 or .aac files, which returns a series of lines like "./root2/folder3/file4.mp3". Then, use cut to remove everything but the first three parts of the path "./root2/folder3". Finally, use sort -u to discard any duplicates.

share|improve this answer
My bad, I didn't read your answer to the end. Thank you! – Max Beikirch Mar 29 '13 at 9:23

Locate all files ending in mp3 or aac, strip the file name with sed and print only one occurance of each folder.

locate  --regex '.*(aac|mp3)$' | sed -e 's,/[^/]*$,,' | uniq
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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