Johan Johan -4 years ago 97
Linux Question

In Bash, move files to directories according to their names

I have lots of files whose names have the following format :

GroupName - SongName-id.mp3
where id is 11 characters long. I'd like to move them in directories such as the file
GroupName - SongName-id.mp3
will be renamed

I've done some research on the web (like this), but I don't know how to retrieve the
using grep.
EDIT : the GroupName directory can already exist or not, it depends.

I first tried using the following script:

for filename in *.mp3;do
group=$(echo $filename | grep -oE ".* - .*-.{11}\.mp3")
# I don't know what regex should I place above

# do all the other stuff here ...

Answer Source

Consider the following complex solution:


find . -regextype sed -regex '[^-]* - [^-]*-.\{11\}\.mp3' -print0 | while read -r -d $'\0' file
    IFS=\; read -a parts  <<< $(sed -E 's:.+/(\S[^/-]+\S) - (\S+)-\S{11}(\.mp3):\1;\2\3:' <<< "$file")
    mkdir -p "${parts[0]}"
    mv "$file" "${parts[0]}/${parts[1]}"


  • -regextype sed (in find command) - set type of regular expressions

  • -regex (in find command) - option used to find files by regex pattern

  • -print0 and $'\0' - ensure separating filenames by zero (null) character

  • read -a parts - read sed result (returns groupname and filename separated by ;) into array

  • mkdir -p "${parts[0]}" - create directory with a name of groupname if not exists

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download