Easy way to get directory names above Parent?


I've been using mp3tag for a while, and very much love it! Especially after updating recently and finding the few annoyances I'd lived with had gone away. Yesterday I discovered 'Actions' and decided to try my hand at further automating my file tagging. I've got most of what I want working, but I'm wondering if there is an easy way to get the directory name that is one above _Parent_Directory? I save files in the following formats:

%artist%\%album%\%track% - %title%
%artist%\%year% - %album%\%track% - %title%
%artist%\%album% [nCD]\CDn\%track% - %title%
%artist%\%album% [nnCD]\CDnn\%track% - %title%
%artist%\%year% - %album% [nnCD]\CDnn (subalbum title)\%track% - %title%

and so on, using CD1, CD2 etc for multiple disk albums.

So sometimes I want to get the artist from the second directory back (which I get with _Parent_Directory), and sometimes the third. Is there an easier way than... Come to think of it, how can I search from the right for the correct occurrance of ""?

If this is not so easy, then I'll make a suggestion for a function that would return the x higher directory :music:

Thanks for any help. Mp3tag is really a great piece of software! I used to follow the Vim development when I used it at work, and now I have a substitute obsession for home :sorcerer:


You could use %_folderpath% for the entire directory structure, plus the functions $strrchr(x,y) and $right(x,n) to extract only the folder level you're looking for.

I was looking at that. $strrchr and $strchr only find the last or first occurrance of a character, so I'd have to successively strip off lower directories. Are there such things as user variables or do I have to use unused tags? I'm thinking I'd have to use $left twice to get to the right place, then $right to pluck out the directory I want, but I'd also need the string lengths of the intermediates, and thus the intermediate storage and multiple Format Value entries. Arggg. These long strings hurt my head.

You won't need to use variables to do that. You can nest the functions, the result will be a pretty convoluted string of functions, but it can work.

I should have suggested Regular Expressions though. You should probably use $regexp(string,regex). A working regex to get the last folder is ".\\([^\\]+)\\" (no quotes). Add "(.?\\){1}" to the end to get the second to last folder, change it to "(.*?\\){2}" to get the third to last, etc. These don't actually work in $regexp() though, because I'm not sure how to format that regex to work inside the mp3tag function (does it need quotes? escape chars? The help file is completely unclear on this). The regex DOES work though, you can confirm it on http://gskinner.com/RegExr/, go to the Replace tab, type your folder string into the first big box, put the regex in the first small box and "$1" in the second small box.

Although Mp3tag has no concrete list oriented functions, like ItemCount or ItemExtract, there might be a trick to simulate such functionality.

"Format value" a temporary tag field e. g. MYFOLDERPATH with the value
This should split the folder path into its components and create multiple MYFOLDERPATH tag fields in extended tag view dialog.

Using scripting function $meta(MYFOLDERPATH,N) you can fetch the Nth item from the folder path.

Using scripting function $meta(MYFOLDERPATH,$sub($folderdepth(%_FOLDERPATH%),N)) you can fetch the Nth item (zero based) from the right side of the folder path.

After all is done you can remove the temporary tag field.


Following example of an Action Group "SplitFolderpath" demonstrates how to split the content of the Mp3tag system variable _FOLDERPATH into it's folder components and make the folder names available for scripting by owner defined tag fields.

MY_FOLDER_0 is the parent folder of the related file.
MY_FOLDER_1 is the next folder up.
MY_FOLDER_2 is the folder two steps up.
... and so on.

Begin Action Group SplitFolderpath

Action #1
Actiontype 5: Format tag field
Formatstring: %_FOLDERPATH%

Action #2
Actiontype 16: Split fields by separator
Separator: </b>

Action #3
Actiontype 5: Format tag field
Field: MY_FOLDER_0
Formatstring: $meta(MY_FOLDERPATH,$sub($folderdepth(%_FOLDERPATH%),0))

Action #4
Actiontype 5: Format tag field
Field: MY_FOLDER_1
Formatstring: $meta(MY_FOLDERPATH,$sub($folderdepth(%_FOLDERPATH%),1))

Action #5
Actiontype 5: Format tag field
Field: MY_FOLDER_2
Formatstring: $meta(MY_FOLDERPATH,$sub($folderdepth(%_FOLDERPATH%),2))

Action #6
Actiontype 5: Format tag field
Field: MY_FOLDER_3
Formatstring: $meta(MY_FOLDERPATH,$sub($folderdepth(%_FOLDERPATH%),3))

Action #7
Actiontype 9: Remove fields
Fields to remove (semicolon separated): MY_FOLDERPATH

End Action Group SplitFolderpath (7 Actions)



Thanks for the regexp info. I ended up doing pretty much what you said, in two steps (2 separate Format Value's).

The first strips the path of the last two directories (I previously set up discnumber to be nonzero if I need to look for the grandparent directory instead of the parent):
ARTIST := $if($eql(%discnumber%,0),%_parent_directory%,$regexp(%_folderpath%,'\\[^\\]+\\[^\\]+\\ ,))

The second strips off everything up to the last directory in the previous result:
ARTIST := $if($eql(%discnumber%,0),%artist%,$regexp(%artist%,'.*\\',))


I'm a little confused. Did your second message override the first? The bit about using $replace to create an array of MYFOLDERPATH entries doesn't compute, but your use of Action "split fields by separator" does. Without $folderdepth this method would be harder:) It should be documented in the list of scripting functions. It's good to be aware of the meta function though, I had overlooked it. Are the above (replace?, split fields) the only ways to get multiple occurrences of a field for meta to act upon?

Thanks all for your help.


I've tried the first proposal in a manual way step by step and because it did work for me I thought it could be worth to throw it in and see what will happen.
Hmm, maybe the first proposal needs a [Ctrl]+[S] saving or so to make the splitting permanent.

I like my second proposal, because it is clean and efficient and easy to understand.

$folderdepth(%_folderpath%) ... can be simulated by ... $sub($sub($len(%_folderpath%),$len($replace(%_folderpath%,'\',))),1) ... or ... $sub($len(%_folderpath%),$len($replace(%_folderpath%,'\',)),1) ... or ... $sub($len($regexp(%_folderpath%,'[^\\\\]',)),1)

As I understand the $meta(...) functions, those functions can only handle and work with an instantiated multi value tag field, but cannot handle a simple string which comes along as a delimited list.

DD.20091117.1900.CET, DD.20150116.1932.CET

Very cool string. Thanks!