Create a unique folder name for each instance of same album

Hi everyone,

I have my music organised by artist, with a folder underneath for each album. For example, in a ‘Richard Marx’ folder I have folders for his ‘Richard Marx’ and ‘Repeat Offender’ albums:

  • Richard Marx/Richard Marx
  • Richard Marx/Repeat Offender

Picard is doing the moving/renaming for me without a problem. But I’ve got music scattered all over my hard drive, and quite often I find another version of the same album by the same artist. And right now they all get put into the same album folder

Can I create a script that checks whether the album folder exists, and if it does creates a unique folder (e.g. by adding a number or something) so multiple albums by the same artist would have their own folder? So it would look something like this:

  • Richard Marx/Repeat Offender
  • Richard Marx/Repeat Offender 1
  • Richard Marx/Repeat Offender 2

I know it’s a long shot, but the scripting seems pretty extensive. Unfortunately I’m not clever enough to create such a beast.

Thanks.

Bill.

1 Like

I don’t personally know if there’s introspective capabilities of the File Naming function, but the way I handle releases that have the same name (usually singles that share the title of the album, or re-releases that are different enough from the original to warrant their own collection) is to lean on some other characteristic that defines them, such as the release year with $left(%date%,4),0000.

This would get you the following:

Richard Marx/Repeat Offender 1989 for the album

However, the pitfall is collisions when, for instance, the single and album were released on the same date (as is the case with Repeat Offender).

To get around this, you could use the full date, and append the release type (single, ep, album, etc.) with %releasetype% in your file naming script.

This would get you the following:

Richard Marx/Repeat Offender (1989-05-02) (album)

Richard Marx/Repeat Offender (1989-05-02) (single)


Full File Naming Script:

$if2(%albumartist%,%artist%)/
$if(%albumartist%,%album%,) (%date%) (%releasetype%)/
$if($gt(%totaldiscs%,1),%discnumber%-,)
$if($and(%albumartist%,%tracknumber%),$num(%tracknumber%,2) ,)%title%
2 Likes

I add catalogue numbers to my releases to avoid directory collisions with same album names by an artist.

(%catalognumber%, [%catalognumber%],)

1 Like

Thanks, everyone. I’ll give those a shot.

Bill.

1 Like

Sorry for the late response, but you could also use the $datetime() function and include that in the output directory name. Unless two albums are processed in the same second, this should create unique directory names. Of course, it wouldn’t help combine tracks into an album if you were processing a random collection of tracks.

2 Likes

I think I tried this. But it ended up creating multiple folders for the same album because of the seconds at the end.

Is there way I could grab the result of the $datetime() function at the beginning, store that in a variable and then use that variable to create thge folder name?

Something like this (excuse my crude coding skills)

%foldername% = $datetime()
$if2(%albumartist%,%artist%)/ $if(%albumartist%,%album%,) (%foldername%) (%releasetype%)/ $if($gt(%totaldiscs%,1),%discnumber%-,) $if($and(%albumartist%,%tracknumber%),$num(%tracknumber%,2) ,)%title%

You could constrain the date to the first 13 characters, so it ignores the seconds with the following:

$if2(%albumartist%,%artist%)/
$if(%albumartist%,%album%,) ($left($datetime(),13))/
$if($gt(%totaldiscs%,1),%discnumber%-,)
$if($and(%albumartist%,%tracknumber%),$num(%tracknumber%,2) ,)%title%

This would get you something along the lines of the album name + the hour and minute (in 24 hour time format).

It should look something like this:

 Repeat Offender (2025-10-12 16)

with 16 being 4:00pm.

You can increment/decrement the number 13 in the code above to manipulate how much of the date is printed to the folder name.

1 Like

Yes. You could save the timestamp to a persistent variable and use that in your file naming script. Of course, this requires that you install the Persistent Variables" plugin. Usage information is available on the github repository.

The timestamp would be set in a tagging script such as:

$set_a(_timestamp,$if2($get_a(_timestamp),$datetime(\%Y-\%m-\%d \%H.\%M.\%S)))

You would then use the resulting value from $get_a(_timestamp) in your file naming script. Note that this uses periods for the separators in the time portion rather than colons (which would be replaced with underscores automatically by Picard).

Brilliant! Thank you.

1 Like

I’ve been attempting to do this without success. When I first attempted it I simply copy/pasted what you put, and it works. I then adjusted your format to remove the hypens and periods (just want a string of numbers), but the hypens and periods kept showing up (I suspect something to do with it being the default format). I then started from scratch with different names in case something legacy was interferring. In tagging script I have:

$set_a(_now,$if2($get_a(_now),$datetime(\%y\%m\%d\%H\%M\%S)))

And in my naming script I have:

$set(now,$get_a(_now))

And in the paths I use %now% where I want the timestamp to show up, but I get nothing. I do have the Persistent Variables plugin enabled. Any advice on what to try to troubleshoot this?

I’ve been using this kind of thing for years:

$noop(Use e.g. Vinyl A1...B5 as tracknumber when renaming)
$set(musicbrainz_tracknumber,
	$if(%_musicbrainz_tracknumber%,
		$if($not($rreplace(%_musicbrainz_tracknumber%,[0-9],)),$num(%_musicbrainz_tracknumber%,2),%_musicbrainz_tracknumber%),
		$num(%tracknumber%,2)
	)
)
$set(non_music,
		$if2(
			$if($in(%releasetype%,audiobook),[audiobook]/),
			$if($in(%releasetype%,spokenword),[spokenword]/),
			$if($in(%releasetype%,interview),[interview]/),
	)
)
$set(disc_info,
	$if2(
	$if($eq(%releasestatus%,promotion), \(promo\))
	$if($eq(%releasestatus%,bootleg), \(bootleg\))
	$if(
		$if($ne(%totaldiscs%,1),%discnumber%,)
		,
		 \(disc $if($gt(%totaldiscs%,9),$num(%discnumber%,2),%discnumber%)$if(%discsubtitle%,: %discsubtitle%)\)
	)
	$if(%bonusdisc%,\(bonus disc$if(%bonusdisctitle%,: %bonusdisctitle%)\))
	)
)
$if($ne(%album%,[non-album tracks]),
	$set(album_after,
		[
			$if(%date%,%date%$set(x,\, ))
			$if(%releasecountry%,$if2(%x%)%releasecountry%)
			$if(%disc_info%,] %disc_info% [,\, )
			%totaltracks%trks
		]
		$if(%catalognumber%, \(%catalognumber%\))
	)
	$set(incomplete,$if($is_complete(),, –incomplete–))
	$set(album_before,$if(%originaldate%,$left(%originaldate%,4),$left(%date%,4)))
)
$set(alphatag,
	$if($eq(%compilation%,1),
		,
		$firstalphachar($upper($if2(%albumartistsort%,%artistsort%)),[num])/
	)
)
$noop(Naming the file)
$noop(filetype directory --fixme e.g. id3 tagged ape-files)
$if2(%_extension%,[fixme])/
%non_music%
$noop(alphatag directory)
%alphatag%
$noop(artist directory)
$if2(%albumartistsort%,%artistsort%)/
$noop(releasetype directory)
$if(%non_music%,
	,
	$if2(
		$if($in(%releasetype%,live),live),
		$if($in(%releasetype%,demo),demo),
		$if($in(%releasetype%,soundtrack),soundtrack),
		$if($in(%releasetype%,compilation),compilation),
		$rreplace(%releasetype%,;.+,)
	)/
)
$noop(album directory)
%album_before% $rreplace(%album% %album_after%,[ \t\n]+, )%incomplete%
/
$noop(filename)
$if2(%musicbrainz_tracknumber%,$num(%tracknumber%,2)). $if(%compilation%,%artist% - )%title%

Of course, if you pick exactly the same version of the release in Picard, it will go in the same directory. After saving, you’ll see if the file names have the extended filename like (1).

An example of some versions of same release:

/music/flac/R/Rage/album/2006 Speak of the Dead [2006-03-24, XE] (disc 1_ Suite Lingua Mortis) [8trks] (NB 1483-1)/A1. Suite Lingua Mortis, Part 1_ Morituri te salutant.flac

/music/flac/R/Rage/album/2006 Speak of the Dead [2006-03-22, FI, 17trks] (NB 1483-0)/01. Suite Lingua Mortis, Part 1_ Morituri te salutant.flac

/music/flac/R/Rage/album/2006 Speak of the Dead [2006-03-27, RU, 16trks] (CDM 0106-2419_d)/01. Suite Lingua Mortis, Part 1_ Morituri te salutant.flac

/music/mp3/R/Rage/album/2006 Speak of the Dead [2006-02, XE] (promo) [15trks] (NB 1653-2)/01. Suite Lingua Mortis, Part 1_ Morituri te salutant (voice-over).mp3
1 Like

I just tried your revised tagging script here and it works fine, although I would have used %Y (upper-case to get the full 4-digit year) but that’s just a personal preference.

If nothing is showing up at all, then I have to question whether the tagging script is executing. Note that the tagging scripts are only run automatically when a release is retrieved from MusicBrainz and that the ‘album’ type persistent variable is only available to that album. All bets are off if you are doing your work in the clustering pane (even if you manually run the tagging script) because there is no Release MBID available so the persistent variable is not created.

One way to check the setting of the persistent variable (and whether or not it has been set) is by right-clicking on a track and open the “Plugins” > “View persistent variables” window.

2 Likes

I don’t know how to explain it, but it’s working now and I didn’t change anything. It must have known you were on the case. Thanks for your attention, Happy Halloween!

2 Likes

I tried to combine two of my efforts into one and I’m running into a wall. I have another thread where I’m determining the source of the files, and then this thread where I’m creating a unique datetime serial number, so I thought, hey, combine them! The problem is, I can’t get it to work right.

$set_a(_dt,$datetime(\%y\%m\%d\%H\%M\%S))
$set_a(_path,%_dirname%)
$set_a(_source,$substr($get_a(_path),36,$add(36,$find($substr($get_a(_path),36),\\))))
$set_a(_letter,$firstalphachar($substr($get_a(_path),36)))

$set(_juaid,$get_a(_letter)$get_a(_dt))

$set(source,$if2(%source%,$get_a(_source)))
$set(juaid,$if2(%juaid%,%_juaid%))

I establish the data at the top, getting a date/time string and the first letter of the source, and those all shows up fine when I inspect the variables. The source tag always comes out fine, but the ‘juaid’ tag won’t show the ‘_letter’. It shows a ‘#’ instead (eg. ‘#251103160121’). I’ve tried using $substr($get_a(_path),36,37) to get the letter, no improvement. If I change the order, with letter last, then I just get ‘#’. It’s strange because the letter shows up fine when I inspect the variable ‘_letter’, but not when I try to combine it with the datetime. As I’m typing this I just wondered, is it because I’m trying to combine ‘text’ and a date/number to the same tag? I’ve tried every workaround I can think of, the only luck I’ve had has been using set instead of set_a for defining things, which shows both the letter and numbers, but then I don’t get the same serial number for every track on the album. See anything obvious I’m missing here?