I have a music collection organized as ./Music/Genre/Artist/Album/Disk#/song.flac. I want to add an ALBUMARTIST tag to every FLAC file that does not already have one, using the Artist directory from each file's path as the tag value. I can do this manually for one artist with metaflac, but doing it for the entire collection would be tedious. How can I extract the artist name from each path and safely combine that with metaflac without overwriting existing ALBUMARTIST tags?
2 Answers
You can loop through the FLAC files, check each file’s metadata first, and only run metaflac when no ALBUMARTIST tag is present. Since the artist is the fourth directory from the end, split the path into variables and use the artist variable in the command. Start with echo enabled so you can review the commands before changing anything:
find Music -type f -name '*.flac' -print | while IFS= read -r songfile; do
if metaflac --list "$songfile" | grep -qEi 'album[[:space:]]*artist'; then
continue
fi
IFS=/ read -r _ genre artist album disk song <<EOF
$songfile
EOF
echo metaflac --set-tag="ALBUMARTIST=$artist" "$songfile"
done
If the printed commands look correct, remove echo to apply the changes.
For a path like ./Music/Genre/Artist/Album/Disk#/song.flac, you can remove the last three path components and then take the final remaining component. In shell syntax, that looks like this:
songfile='./Music/Genre/Artist/Album/Disk#/song.flac'
artistPath=${songfile%/*}
artistPath=${artistPath%/*}
artistPath=${artistPath%/*}
artist=${artistPath##*/}
Here, %/* repeatedly strips everything from the last slash onward, while ##*/ strips everything through the first slash from the left, leaving the artist directory name. The loop-based solution is generally more useful because it also checks for an existing tag before calling metaflac.

Thanks, but I’m still learning shell scripting. Could you explain what the path-splitting part is doing or suggest terms I can search for?