2 Actions: Append term to Genre unless term already exists and distribute terms to fields if not duplicated

For my second task, I have tried to use guess values with no success.
In Genre I have the following value: "Classic Rock / Hard Rock / Live / Live / GB / eng"
I thought that if I created a guess value with %genre% being the Source Format and the guessing pattern being "%genre1% / %genre2% / %genre3%"
That MP3Tag would populate Classic Rock to GENRE1, Hard Rock to GENRE2, Live to GENRE3 but it does not work.
If I change the guessing pattern to "%genre% / %genre2%"
Then I get Classic Rock to GENRE and Hard Rock / Live / Live / GB / eng to Genre2, so I believe I am close but yet have no cigar.

I don't know why the first term has to be %genre% but it does not work unless it is. I also realized that if I only had 5 genres but the action defines 10 genres, it does not work, so the Action requires some component that "sees" how many genres there are, maybe a $if function? The solution is falling further from my reach. :frowning:

Yes, it is impossible to use Guess Value in one go, given the way it works (shortest possible match). However,

I believe it's totally unrelated to %genre% tag, but depends on number of fragments.

BTW, what you want to achieve can be done iteratively, if you don't mind the repetitiveness.

  1. Copy the genre list into a temp tag, say %TEMP% but with some caveat: you need to append " / " (space slash space) to the end of temp tag. Anyway it should be the same separator you used everywhere.
  2. Guess Values:
    Format: %TEMP%
    Pattern: %genre1% / %TEMP%
  3. Repeat the guess value as many times as necessary, chopping the temp genre list one by one into genre fragments until done.
  4. If you don't append the final separator, the last guess action will fail, and you won't be able to write the final genre.

Thanks again for your help! I see what you are doing here but I wonder why I would need to copy the values to %temp%?
Would it not work with
Format: %genre%
Pattern: %genre1% / %genre%
I am not sure what copying the values to %temp% accomplishes.

For safety. You won't lose any data in case anything has gone wrong.

The guessing pattern has to match the source string exactly in that respect that the guessing pattern must not contain more target fields than the source offers.

For the other list:
Here is a thread that deals with the removal of duplicate string parts from a list of words in a string:

Perhaps you could use that to get rid of duplicates and save yourself a number of $if().

Then, instead of the manually numbered genre fields, it may be an idea to create several fields of the type genre which then could be merged and separated with actions that do not need constant maintainance. Have a look at the $meta() and $meta_sep() function as well as the actions to merge and split fields.

OK, sounds like a good plan, if maybe unnecessary, but I guess it is better to be safer than sorry.

I have solved the first issue using this Action:
Format Value:
Field: Genre
Format String: $trim($regexp(%Genre%,'(?:(?<=/)|(?<=\A))\s*([^/])\s/(?=.?(?<=/)\s\1(?=/|\Z))',,1))

This will get rid of the duplicates in Genre.
I got it from here Merge duplicate words - #10 by dano

I really hope I can figure out how to propagate the specific genres from the Genre field (My second question) as I stupidly erased them after consolidating them in the main Genre field. I will play with abelcheung's suggestion and see if I can get something working.

Have you found out whether your player can cope with multiple entries in GENRE?
Or does it react to a single string separated with special separators, like comma, semicolon or slash?
Can your player cope with user-defined fields and does it then group these together to just 1 genre?
The answers to these questions would then determine the way to go about.

I use the genre field to create smart playlists. Genre contains: X. iTunes has no problems using them. I also know I can change the delimiter to // (or is it '\\') so they are read by foobar as separate genres, but for now I am sticking to iTunes.

Does iTunes read fields like

? Not AFAIK.
So I would think that you address only the actual GENRE field with iTunes and all the other data is lost/ignored.
So I would assume that a comma-separated list in GENRE would be read by iTunes, but user-defined fields would not.

You can use any GENRE name you like in iTunes. However it will not separate them. So for Christmas / Blues / Subdued this will be exactly the single GENRE that is displayed (not separated).

Yes. I hope that at some point I would put those fields to use in the future but as MotleyG surmised they would show up as single fields with all the forward slashes.

If I could get a handle on foobar I am sure it would suit my needs but I do not have the time to deal with another app that comes with a large learning curve. IMatch is taking all I can give.

Meanwhile I am still trying to crack the puzzle of the second function. Currently writing a action that may work...

No need to be surprised, iTune has been notorious for resistant on the idea of having multi-value tags. I still remembered the time spent on salvaging my music library after multivalued ID3 v2.4 tags were all overwritten with random junk memory after iTune saves tag.

But no need to hurry, familiar youself with various tools first. You can switch player anytime when it feels right.

Apple has never suggested that iTunes would ever support multiple tag fields. But the same goes for many other players. What is important here is to recognize what the player of choice can do.

To get the second question addressed, you will have to start filtering by the number of separators you have in the genre. So wherever you have say four genres (so three slashes “/“) you can use this action
Guess values
Source: GENRE
Pattern: %genre1%/%genre2%/%genre3%/%genre4%

And do the same adjusting for more or less after filtering.

EDIT: I just noticed in your original post example that you have spaces before and following each slash. If you wish to avoid having these captured in the field data, make sure to include them in the pattern like below. Every character matters, even a space.
Pattern: %genre1% / %genre2% / %genre3% / %genre4%

1 Like

Here is a filter that should filter for the set number of slashes (3 in this case)
"$len($regexp(%genre%,'[^/]',))" IS 3

1 Like

Thanks guys! Sorry I was busy with other matters until now. So I will use ohrenkino's filter (THANK YOU! that will be very useful) and then use MotleyG's suggestion for an action. It will be laborious, doing it piece-meal but the pain will stop me for making the same mistake again. I really don't know why I erase information when I can always store it in a custom tag.

I was working on cleaning up my genres with the tools given by MotleyG & ohrenkino and realized that the script I was using to append genres

%genre%$if(%genre1%, / %genre1%,)$if(%genre2%, / %genre2%,)$if(%genre3%, / %genre3%,)$if(%genre4%, / %genre4%,)$if(%genre5%, / %genre5%,)$if(%genre6%, / %genre6%,)$if(%genre7%, / %genre7%,)$if(%genre8%, / %genre8%,)$if(%genre9%, / %genre9%,)$if(%genre10%, / %genre10%,)

had a flaw where if %genre1% was not populated, %genre% would start with a Forward Slash (/).

I modified it to work if genre1 was not populated, using this
$if(%genre1%,%genre1%,)$if($and(%genre1%,%genre2%), / ,)$if(%genre2%,%genre2%,) and so on...
But if %genre2% was not populated, then I would still have the forward slash and the beginning of %genre%.

I tired to write something that would instruct MP3Tag to only insert the forward slash if a genre existed and if any of the previous ones existed, but I could not get it to work.
I tried
$if($and(%genre3%,(%genre2%|%genre1)), / ,)
but that will result in a forward slash in the beginning of %genre% even if there is no %genre1% or %genre2%, so there must be something wrong with the script..

How could I change this to get the desired result?

I still think that these numerous user-defined fields are not really the best solution.


Try and action of the type "Format value" for GENRE
Format string: %genre%[ / %genre1%][ / %genre2%][ / %genre3%]
(and so on)

Yes, this may not be the best solution, and believe me I do weigh your objections to my strategies. But after consideration, I still think this best suits my purposes. It is nice to have individual fields one can change without having to edit a field with a lot of values, plus I can repurpose some tags to other fields if they are discrete. For example, I used to include a country code, language and mood in my genres (I know you probably object to this as well) and now I have moved them to dedicated fields and then write them in shorthand to the comments field to aid in smart playlist creation.

Unfortunately, your script still produces a leading Forward Slash if genre1 and genre2 were not present. I need to only put the forward slash if ANY of the previous genres were present. So in a 3 genre example, genre3 will only produce a " / " preceding it IF a genre3 exists AND either genre1 OR genre2 is present. (Capitalizing what I assume would be functions).

Really there should not be any instance that genre1 should not be populated, but since I just created it, as I was using genre as genre1 (see script in 1st post), it brought about this problem that I had not considered (because genre was always populated).

I did populate all genre1s after I noticed this but I thought I would fool-proof the script in case, for some reason genre1 was no populated for whatever reason.

Are you sure that you used the square brackets?

a leading slash will only appear if GENRE is not filled but %genre1% (or any of the subsequent ones) is filled.
You can try that in Converter>Tag-Tag.

The reason why I am a little reluctant about the user-defined fields with an index in the name is that you have to hard-code the names into all the actions that rely on these fields.
If you use a multi-value-field then you can merge the data of several fields into one and treat them in one go - and split them afterwards again. But, of course, you are .free to do what you want.
In this case it looks like the current approach produces a number of problems that need the help of the forum.

Unfortunately I really am not versed enough to understand why hard coding the names into the actions can cause problems, nor do I expect you to explain why. It will probably go over my head anyway. I will say that if I tried to use one field, I would probably have just as many questions of how to split and reassign, as this very thread proves! But you may be right, what do I know?

I did as you suggested and tried Tag-Tag and with nothing in genre1 & genre2 and "Space Rock" in %genre3% the result is "/Space Rock"

I think its because in your script you instruct MP3Tag to add the " / " if there is a Genre3, but you do not, AFAIS, place a condition that either genre1 or genre2 must exist to add the preceding " / ". IF only Genre3 exists, it should be inserted without the forward slash preceding it.

Like I said, there should be no reason why genre1 would not be populated, so this probably will never be a problem, as the script as it stands can handle any other genre field after genre1 being blank, but I am doing this more to try to learn how to do this with Reg Ex as an exercise as well as to foolproof the script. I can survive without solving this, but since I am trying to grasp Reg Ex, I thought I would see it through. Unfortunately I cannot solve it so I came here but I don't want to impose if it is too much trouble.

I do appreciate your help and input as always! :raised_hands: :clap: