Want to batch rename mp3 files to following scheme
my-artist_my-title.mp3
E.g.:
Let's suppose that I have the mp3
file: of the song Underground‐Čoček, by Goran Bregović. But the file is named s3 24)3ü6 Dț67 .mp3
(for exaple, because it was lost on a drive and recovered with testdisk
. Supposing the mp3 metadata is correct, the script should change the filename to:
goran-bregovic_underground‐cocek.mp3
Ideally I would prefer to have a bash script
which I would trigger with:
$ rename-mp3 directory-with-subdirectories-with-mp3-files
Searching for similar solutions I found this function. I modified it and it works, partially! The regex modifications, marked with #?
are not working.
function rename-mp3() { # input is an mp3 file: i.e. find -name 's3 24)3ü6 Dț67 .mp3' -exec bash -c 'rename-mp3 "$@"' bash {} \;
# extract metadata from file
artist=`ffprobe -loglevel error -show_entries format_tags=artist -of default=noprint_wrappers=1:nokey=1 "$1"`
title=`ffprobe -loglevel error -show_entries format_tags=title -of default=noprint_wrappers=1:nokey=1 "$1"`
artist="${artist/\&/}" #? delete all non-numeral, non-latin, and non-space characters (&, %, !, ', ä, ö, ü, ă, ț, etc.)
title="${title/\&/}" #? delete all non-numeral, non-latin, and non-space characters (&, %, !, ', ä, ö, ü, ă, ț, etc.)
artist="${artist// +/\-}" #? replace all spaces with "-", if more then one in sequence substitute only one "-"
title="${artist// +/\-}" #? replace all spaces with "-", if more then one in sequence substitute only one "-"
filename="$artist_$title.mp3" # paste artist and title together
filename="${name,,}" # lowercase everything
echo "$filename" # display new filename
cp "$1" "renamed/$name" # copy renamed file to the renamed folder
}
I'm using a similar script (but really more complicated) to sort all my audio files.
Based on your script:
#! /usr/bin/env bash
declare -r input_filename="$1"
declare -r output_dirname="$2"
function rationalize() {
local s="$1"
# extglob option is necessary for pattern matching in bash expansions
shopt -s extglob
# delete all non-ascii characters
s="${s//[^[:ascii:]]/}"
# keep only all alpha, numeral and space characters
s="${s//[^[:alnum:]|[:space:]]/}"
# replace all spaces with "-", if more then one in sequence substitute only one "-"
s="${s//+([[:space:]])/-}"
shopt -u extglob
printf "%s" "$s"
}
function get_tag() {
local -r tag="$1"
local -r filename="$2"
local value=$(ffprobe -loglevel error -show_entries format_tags="$tag" -of default=noprint_wrappers=1:nokey=1 "$filename")
value=$(rationalize "$value")
printf "%s" "$value"
}
function copy_audiofile() {
local -r from_filname="$1"
local -r to_dir="$2"
# get filename extension
local -r ext="${from_filname##*.}"
# get artist for file
local artist=$(get_tag "artist" "$from_filname")
# get title for file
local title=$( get_tag "title" "$from_filname")
# paste artist and title together
local filename_to="${artist}_$title.$ext"
# lowercase everything
filename_to="${filename_to,,}"
# display new from_filname
echo "Rename '$from_filname' to '$filename_to'"
# copy renamed file to the renamed folder
cp "$1" "$to_dir/$filename_to"
}
copy_audiofile "$input_filename" "$output_dirname"