I\'m trying to sort all mp3 files by artist and name. At the moment, they\'re in 1 giant file name. E.g Artist - Song name.mp3 I want to convert this to Artist/Song name.mp
Just in case you don't have the rename
utility. A fix on your original script.
for f in *.mp3; do
# extract artist and song name and remove spaces
artist=${f%% -*}
song=${f##*- }
#make directory with the extracted artist name and move + rename the file into the directory
echo mkdir -p -- "$artist" && echo mv -- "$f" "$artist/$song"
done
echo
If you're satisfied with the output.By far the simplest way of doing this is to use rename
a.k.a. Perl rename
.
Basically, you want to replace the sequence SPACE-DASH-SPACE with a forward slash directory separator, so the command is:
rename --dry-run -p 's| - |/|' *mp3
Sample Output
'Artist - Song name.mp3' would be renamed to 'Artist/Song name.mp3'
'Artist B - Song name 2.mp3' would be renamed to 'Artist B/Song name 2.mp3'
If that looks correct, just remove --dry-run
and run it again for real. The benefits of using rename
are:
-p
optionNote that you can install on macOS with homebrew:
brew install rename
Assuming there are many files, it's probably much faster to do this using pipes instead of a for loop. This has the additional advantage of avoiding complicated bash
-specific syntax and using core unix/linux command line programs instead.
find *-*.mp3 |
sed 's,\([^-]\+\)\s*-\s*\(.*\),mkdir -p "\1"; mv "&" "\1"/"\2",' |
bash
Explanation:
This find
to find all the files matching -.mp3 in the current directory.
This sed
command changes each line to a command string, e.g.:
aaa - bbb.mp3
->
mkdir -p "aaa"; mv "aaa - bbb.mp3" "aaa"/"bbb.mp3"
The bash
command runs each of those command strings.
you can try this.
#!/usr/local/bin/bash
for f in *.mp3
do
artist=`echo $f | awk '{print $1}' FS=-`
song=`echo $f | awk '{print $2}' FS=-`
mkdir -p $artist
mv $artist-$song $song
mv $song ./$artist
done
here I am using two variable artist and song. as your test file name is "hi\ -\ hey" so I change the awk delimiter to "-" to store variable according to it.
we don't need to use awk..by using bash parameter expansion.... it is working.
#!/usr/local/bin/bash
for f in *.mp3
do
artist=`echo ${f%-*}`
song=`echo ${f#*-}`
mkdir -p $artist
mv $artist-$song $song
mv $song ./$artist
done