I want to change the track and title of mp3 files using their ID3 Tag data in all sub directories too not just the folder I am in.

To change track and title in a single folder sometimes kid3-cli or eyeD3 works for me but, I am willing to try other suggestions (along with kid3-cli or eyeD3 ):

$ kid3-cli -c 'fromtag "%{track}-%{title}" 1' *.mp3

$ find . -name \*.mp3 -execdir eyeD3 --rename '$track:num-$title' *.mp3 {} \;

1 Answer 1


How about ffmpeg?
Well, ffprobe actually, but it's part of the package.


set -o noclobber # just a precaution

get_metadata() {
  local song="$1"
  local song_track=$(ffprobe -v error -of csv=p=0 -show_entries format_tags=track "$song" | awk '{print $1}')
  local song_title=$(ffprobe -v error -of csv=p=0 -show_entries format_tags=title "$song")
  song_track=$(echo "$song_track" | awk '{printf "%02d\n", $0}') # pad track number to ensure it's two digits
  echo "$song_track" "$song_title"

# list mp3s with their full paths
find "$(pwd)" -type f -name "*.mp3" > /tmp/my_mp3_list
readarray -t list_mp3s < /tmp/my_mp3_list

for song in "${list_mp3s[@]}"; do
  IFS=' ' read -r song_track song_title <<< "$(get_metadata "$song")"
  file_name=$(echo "$file_name" | sed 's/[\/:*?"<>|]/_/g') # sanitize bad characters
  dir_name=$(dirname "$song")
  mv -- "$song" "$new_file_path"
  echo "Renamed '$(basename -s .mp3 "$song").mp3' to '$(basename -s .mp3 "$new_file_path").mp3'"

rm tmp/my_mp3_list

exit 0

Save as: rename_from_id3.sh
Change mode executable: chmod +x rename_from_id3.sh
Usage: ./rename_from_id3.sh

Run from the .mp3 directory. All files in that directory will be renamed, recursively.

  • Thank you and yes it worked!
    – Gene Tyle
    Commented May 29 at 15:46
  • Thank you and yes it worked! Anything that did not have a title was named 00-. and is easy to find. It missed some but they can be cleaned up manually. Many songs #08 and #09 often get labeled 00 too but they clean up nicely too manually. For a 700GB folder this was a lifesaver. Thank you again.
    – Gene Tyle
    Commented May 29 at 15:52
  • @GeneTyle Likely too late to matter, but I figured out the 08 & 09 issue. prinf was throwing some octet error, and wrapping the printf with awk solved it.
    – JayCravens
    Commented May 29 at 23:36
  • What would that look like?
    – Gene Tyle
    Commented May 30 at 2:17
  • I updated the script. Changing the number padding to awk '{printf "%02d\n", $0}' fixed the problem with #08 and #09.
    – JayCravens
    Commented May 30 at 3:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .