Generating %DISCNUMBER% Tags

I'm trying to make MP3Tag automatically generate the discnumber field based on the folder structure. Can anyone help me out? I have very limited scripting knowledge - so I'm confused as to where I should even start...

I'd like MP3Tag to recognize if there is a folder in the parent directory named "CD1", "CD2", "CD3", etc., to automatically create a x/x tag in the discnumber field, correctly tagging which directory it is in - and generate a discnumber total.

Also - if there isn't - I would like it to tag 1/1 for the discnumber.

Can this be done?

Thanks very much! :smiley:

I'm guessing the hard part in creating discnumber tags 'x/y' would be the 'y' part - finding the discnumber total. I doubt if it can be done.

I organize my multidisc sets in exactly the same way and never felt it was worth the effort of creating an action that could read the folder to extract the disc number.

ArtistName/
../AlbumName/
../../Disc 1/
../../Disc 2/

Since these albums make up a small percentage of my library, I just tag them manually. What I've found is that if you load up the whole album (all discs) Mp3tag will sort them quite nicely and it makes it easy to select all files on disc 1 and give them DISC and DISCC tags (what I use for Flac), then all files from the disc 2, etc. And since the majority of my multidisc sets are two discs, I've created two actions called 'Disc 1 of 2' and 'Disc 2 of 2' that can handle 99% of the cases.

why doesnt this work?:

$add(%discnumber% ,'/''2')

$add() is a math function that adds two numbers and returns the sum.
It's not made for string concatenation.

The thing that you want to achieve can be done with this action:

Action type: Format value
Field: Discnumber
Formatstring: %discnumber%/2

It would still be nice to have a way to automatically generate the '2' in the above example, the only thing I've been able to think of so far (using existing functionality) is to export a simple text file and read it back in as a taglist.

This is still very manual though.

Maybe you could replace the '2' with a regular expression that gives the last character of %_directory% ?

Thanks for the respone.

I have a function that does that (need to change it to a RegExp), but when the expression runs you don't know if you are on the last directory or not, so the result would always be 1/1, 2/2 , 3/3, 4/4. You'd need to capture the largest number and go back and update the other tracks.

You have a folder/file structure like this:

artist1/album1/cd1/files
artist1/album1/cd2/files

artist1/album2/cd1/files
artist1/album2/cd2/files
artist1/album2/cd3/files

artist2/album1/files

You can try something like this:

  1. Create an actiongroup 'Set DISCNUMBER step 1 (n/x)'
    Action #1:
    Action type: Format value
    Field: DISCNUMBER
    Formatstring: %_DIRECTORY%

    Action #2:
    Action type: Replace with regular expression
    Field: DISCNUMBER
    Regular expression: ^(.*)(\d+)$
    Replace matches with: $trim($2)/x

    [ ] case-sensitive comparison
  2. Create an actiongroup 'Set DISCNUMBER step 2 (n/2)' Action #1: Action type: Replace Field: DISCNUMBER Original: x Replace with: 2 [ ] only as whole word [ ] case-sensitive comparison
  3. Select all the tracks from album1 and run actiongroup 'Set DISCNUMBER step 1 (n/x)'.
  4. Select all the tracks from album1 and run actiongroup 'Set DISCNUMBER step 2 (n/2)'.
  5. Done.
You may create some more actiongroups of type 'step 2' with replacement numbers of 3 or 4 or what you want: 'Set DISCNUMBER step 2 (n/3)'. 'Set DISCNUMBER step 2 (n/4)'.

This is the half automatic way to work around the problem.
It will be better to have a full automatic solution, ...
but therefore we need an extra storage place to hold a user defined value while an action runs against the selected tracks, something like we know from the Mp3tag export section:
$puts(myVar,221)
$get(myVar)

An action that can accept user input on runtime would be nice too.

DD.20070118.1633

This definately gets us closer to full solution, nice work!.
I think that the process can simplified:
 1. Create an actiongroup 'Set DISCNUMBER (n/<i>x</i>)'

Action type: Format value
Field: DISCNUMBER
Formatstring: $regexp(%_directory%,^(.*)(\d+)$,$2)/x

[ ] case-sensitive comparison 2. Create addtional action groups where x is the number of discs that the album contains.

Well, we can make it even a little bit more comfortable for different cases:

  • 'CD 1 The Best of all'
  • 'The Best of all CD1'
  • 'The Best CD1 of all'
  • 'The Best CD 1 of all'
Important is, that there is a character group containing 'CD' in capital letters followed by a number.
  1. Create an action group 'Set DISCNUMBER step 1 (n.x)' ( :astonished: 'n/x' slash is not allowed in the title name ?!?!?)

    Action type: Format value
    Field: DISCNUMBER
    Formatstring: $regexp(%_directory%,^.*CD (\d+).$,$1)/x
    [x] case-sensitive comparison

  2. Create additional action groups 'Set DISCNUMBER step 2 (n.x)' where x is the number of discs that the album contains, e.g.

    Action #1:
    Action type: Replace
    Field: DISCNUMBER
    Original: x
    Replace with: 2

    [ ] only as whole word

    [ ] case-sensitive comparison

You can select both action groups at once and run them against the selected tracks.

DD.20070119.1218


That helps even more, thanks. Can't we combine the two actions though? Instead of having the replace in the second step just create multiple versions of Step 1 with X being 1, 2, 3, etc.

In fact, I think we can add the $if in to create a single action for Disc 1/1 (default, no 'CD' in _directory) and then have Disc x/2 be the else in the statement.

Yes, that's seems to be the most practicable way.

Action group: 'Set DISCNUMBER (n.2)'
Action #1:
Action type: Format value
Field: DISCNUMBER
Formatstring: $regexp(%_directory%,^.*CD (\d+).$,$1)/2

Action group: 'Set DISCNUMBER (n.3)'
Action #1:
Action type: Format value
Field: DISCNUMBER
Formatstring: $regexp(%_directory%,^.*CD (\d+).$,$1)/3

... and so on.

DD.20070119.1624

So this may work:
Action #1:
Action type: Format value
Field: DISCNUMBER
Formatstring: $if($eql($regexp(%_directory%, *(CD) *\d+,$1,0),CD),$regexp(%_directory%, *CD *(\d+),$1,0)/2,1/1)

DD.20070119.1655

Works perfectly, only change I made was to wrap the second RegExp in $num(re,1) in the event that the directory was listed as CD01.

Thanks for your help!

Hoping, that we have it now:

$if($eql($regexp(%_directory%,'^.* *(CD) *\d+.*$','$1',0),'CD'),$regexp(%_directory%,'^.* *CD *0*(\d+).*$','$1',0)'/2','1/1')

DD.20070119.1735

Yep - I think we do.

Wow - I haven't checked this topic in forever. Thanks very much for all your hard work, guys!

Would it be possible for me to get you to alter this? My directory format is a bit different.

Here's how I have my directories:

Ben Harper - Both Sides Of The Gun (2006)\CD1\Files

Thanks again!

Well, I know, that the problem is not solved in general so far (we really need a ready made Discnumber Assistant), but now we have a practical way to handle cases like ...

  • If there is no folder 'CDn' between album and file:
    album/file
  • If there are two folders 'CDn' between album and file:
    album/CD1/file
    album/CD2/file
... by using this
Action #1:
Action type: Format value
Field: DISCNUMBER
Formatstring: $if($eql($regexp(%_directory%,'^.* (CD) \d+.$','$1',0),'CD'),$regexp(%_directory%,'^. CD 0(\d+).$','$1',0)'/2','1/1')

If there is only one folder 'CD1' between album and file:
album/CD1/file
you can simply set DISCNUMBER to '1/1' by
Action #1:
Action type: Format value
Field: DISCNUMBER
Formatstring: 1/1

DD.20070120.1020

Sorry - the problem I was having before was on my end. Another action was interfearing with it.

Either way, the script you posted works perfectly! Thanks very much! :smiley: