I'm trying to get my music folder into something sensible. Right now, I have all my music stored in /home/foo so I have all of the albums soft linked to ~/music. I want the structure to be ~/music/<artist>/<album> I've got all of the symlinks into ~/music right now so I just need to get the symlinks into the proper structure. I'm trying to do this by delving into the symlinked album, getting the artist name with id3info. I can do this, but I can't seem to get it to work correctly.

for i in  $( find -L $i -name "*.mp3" -printf "%h\n")

 echo "$i" #testing purposes

    #find its artist
    #the stuff after read file just cuts up id3info to get just the artist name
 #$artist = find -L $i -name "*.mp3" | read file; id3info $file | grep TPE | sed "s|.*: \(.*\)|\1|"|head -n1

 #move it to correct artist folder
 #mv "$i" "$artist"


Now, it does find the correct folder, but every time there is a space in the dir name it makes it a newline.

Here's a sample of what I'm trying to do

$ ls 
DJ Exortius/
The Trance Mix 3 Wanderlust - DJ Exortius [TRANCE DEEP VOCAL TECH]@

I'm trying to mv The Trance Mix 3 Wanderlust - DJ Exortius [TRANCE DEEP VOCAL TECH]@ into the real directory DJ Exortius. DJ Exortius already exists, so it's just a matter of moving it into the correct directory that's based on the id3 tag of the mp3 inside.


PS: I've tried easytag, but when I restructure the album, it moves it from /home/foo which is not what I want.


You should pipe find into while instead of doing for $(find) in order to properly handle filenames with spaces in them.

You can also use process substitution to accomplish the same thing. You would redirect <(find) into the done part of the while loop.

find -L $i -name "*.mp3" -printf "%h\n" | while read -r i


while read -r i
done < <(find -L $i -name "*.mp3" -printf "%h\n")

The latter has the advantage of not creating a subshell.

  • You mean, the former has the advantage of not creating a subshell. The latter creates a subshell with the use of parentheses. – Daniel Papasian Jun 5 '12 at 14:37
  • @DanielPapasian: It's true that the process substitution is a subshell. However, my first example creates a subshell by piping a command into the while and variable changes and directory changes are lost/reverted when the while loop terminates. The second does not create a subshell out of the while loop so such changes persist after the while loop terminates. Bash 4.2 has an option shopt -s lastpipe to prevent the creation of a subshell in cases like the first example. Certain other shells (e.g. ksh, zsh) do not create a subshell in the circumstances represented by the first example. – Dennis Williamson Jun 5 '12 at 15:58

If you use hard links instead of symlinks then you can leave your unordered pool in place while using EasyTAG to restructure the links.

  • How would I automatically hard link everything into ~/music though? I can do a find . \( -name "*.mp3 -o -name "*.flac" \) to get all of the songs, but then how would I link automatically to ~/music? – Reti Apr 3 '10 at 22:51
  • -exec cp -l -t ~/music {} + – Ignacio Vazquez-Abrams Apr 4 '10 at 2:18

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.