Difference between revisions of "ReNamer:Pascal Script:SplitPath"
(Arrrghh, another little glitch.) |
(First clean up. Then more examples.) |
||
Line 89: | Line 89: | ||
+ #13#10 | + #13#10 | ||
+ 'Extracted by using functions:' + #13#10 | + 'Extracted by using functions:' + #13#10 | ||
+ | + 'WideExtractFilePath >>> ' + vPath + #13#10 | ||
+ | + 'WideExtractFileDir >>> ' + vDir + #13#10 | ||
+ 'WideExtractFileDrive >>> ' + vDrive + #13#10 | + 'WideExtractFileDrive >>> ' + vDrive + #13#10 | ||
− | |||
− | |||
+ 'WideExtractFileName >>> ' + vName + #13#10 | + 'WideExtractFileName >>> ' + vName + #13#10 | ||
+ 'WideExtractBaseName >>> ' + vBase + #13#10 | + 'WideExtractBaseName >>> ' + vBase + #13#10 | ||
Line 98: | Line 98: | ||
end. | end. | ||
</source> | </source> | ||
− | Or just use the function 'on the fly'<BR> | + | Or just use the function 'on the fly', without using an var first<BR> |
Use this e.g. like:<BR> | Use this e.g. like:<BR> | ||
<source> | <source> | ||
Line 120: | Line 120: | ||
<BR> | <BR> | ||
You can even use this trick more then once:<BR> | You can even use this trick more then once:<BR> | ||
− | |||
<BR> | <BR> | ||
+ | (Here for our example "C:\GreatGrand\GrandParent\ParentFolder\file.ext")<BR> | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! nested Functions | ! nested Functions | ||
− | ! provides | + | ! provides the folder |
|- | |- | ||
| WideExtractFileName(WideExtractFileDir(FilePath)); | | WideExtractFileName(WideExtractFileDir(FilePath)); | ||
Line 149: | Line 149: | ||
</source> | </source> | ||
<BR> | <BR> | ||
+ | <BR> | ||
+ | Other tricks:<BR> | ||
<BR> | <BR> | ||
To get the extension without the dot use something like:<BR> | To get the extension without the dot use something like:<BR> | ||
Line 154: | Line 156: | ||
vExt := WideReplaceStr(WideExtractFileExt(FilePath), '.', ''); | vExt := WideReplaceStr(WideExtractFileExt(FilePath), '.', ''); | ||
</source> | </source> | ||
− | Or step by step:<BR> | + | Or showing this as step by step:<BR> |
<source> | <source> | ||
vExt := WideExtractFileExt(FilePath); | vExt := WideExtractFileExt(FilePath); | ||
Line 164: | Line 166: | ||
<BR> | <BR> | ||
− | Here is an another way by splitting the path at the back slash into an array 'Folders': | + | Here is an another way to get the name of an parent folder of an path<BR> |
+ | by splitting the path at the back slash into an array of 'Folders'.<BR> | ||
+ | <BR> | ||
+ | We use<BR> | ||
+ | Folders: TStringsArray; <BR> | ||
+ | "Folders := WideSplitString( WideExtractFileDir(FilePath), at sign '\')"<BR> | ||
+ | <BR> | ||
+ | to get the elements of such an path.<BR> | ||
+ | Then we can access each level of parent folders<BR> | ||
+ | by referring to the right element in the array.<BR> | ||
+ | Note that an array start counting at '0'<BR> | ||
+ | And if you try to access an array element that is not there,<BR> | ||
+ | you will get an error message "Exception: Out Of Range".<BR> | ||
+ | <BR> | ||
+ | Again for our example "C:\GreatGrand\GrandParent\ParentFolder\file.ext"<BR> | ||
+ | there are 4 elements in the array, counting from '0' to '3'<BR> | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Array level | ||
+ | ! provides | ||
+ | |- | ||
+ | | Folders[0] | ||
+ | | C: | ||
+ | |- | ||
+ | | Folders[1] | ||
+ | | GreatGrand | ||
+ | |- | ||
+ | | Folders[2] | ||
+ | | GrandParent | ||
+ | |- | ||
+ | | Folders[3] | ||
+ | | ParentFolder | ||
+ | |} | ||
+ | If you not know how deep the folder hierarchy is, you may want to count from the right.<BR> | ||
+ | Therefor we can utilize the max. amount of elements in an array. We use the 'Length' attribute here.<BR> | ||
+ | "Length(Folders)" is '4'. But Folders[4] is for our example path "Out Of Range".<BR> | ||
+ | That is why we use "Length(Folders) -1" to get '3'.<BR> | ||
+ | So to get the last element in array use "Folders[ Length(Folders) -1 ]", which is here the same as "Folders[ 3 ]"<BR> | ||
+ | And so we can use '-1' (4 -1 = 3) till '-4' (4 -4 = 0) for our example path. (remember: we have 4 elements, from '0' to '3'.) | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Array level | ||
+ | ! provides the folder | ||
+ | |- | ||
+ | | Folders[Length(Folders)-1] | ||
+ | | ParentFolder | ||
+ | |- | ||
+ | | Folders[Length(Folders)-2] | ||
+ | | GrandParent | ||
+ | |- | ||
+ | | Folders[Length(Folders)-3] | ||
+ | | GreatGrand | ||
+ | |- | ||
+ | | Folders[Length(Folders)-4] | ||
+ | | C: | ||
+ | |} | ||
+ | <BR> | ||
+ | Use this like:<BR> | ||
<source> | <source> | ||
var | var | ||
Line 172: | Line 232: | ||
begin | begin | ||
− | |||
// Get parts of the current file path: | // Get parts of the current file path: | ||
oldPath := WideExtractFileDir(FilePath); | oldPath := WideExtractFileDir(FilePath); | ||
Line 182: | Line 241: | ||
ParentFolder := Folders[Length(Folders)-1]; | ParentFolder := Folders[Length(Folders)-1]; | ||
− | FileName := SecondTopMostFolder + '-' + | + | FileName := SecondTopMostFolder + '-' + GrandParentFolder + '-' + ParentFolder + '-' + FileName; |
end. | end. | ||
</source> | </source> | ||
+ | Tip:<BR> | ||
+ | You can use ShowMessage() like MsgBox to be prompte what the elements contains:<BR> | ||
+ | <source> | ||
+ | ShowMessage('Debug: ' + Folders[1] + ' # ' + Folders[Length(Folders)-1] ); | ||
+ | </source> | ||
+ | |||
+ | To loop trough each element of an part (e.g. to check if an given folder exists)<BR> | ||
+ | you may take an look at this example: | ||
+ | <source> | ||
+ | var | ||
+ | I: Integer; Parts: TStringsArray; | ||
+ | begin | ||
+ | //function WideSplitString(const Input, Delimiter: WideString): TStringsArray; | ||
+ | Parts := WideSplitString(FilePath, '\'); | ||
+ | for I:=0 to Length(Parts)-1 do | ||
+ | begin | ||
+ | // access each part via Parts[i] | ||
+ | end; | ||
+ | end. | ||
+ | </source> | ||
<BR> | <BR> | ||
--------------------- | --------------------- | ||
<BR> | <BR> | ||
− | And | + | And you could use Regular Expression to extract the parts of an part: |
− | |||
− | |||
<source> | <source> | ||
Parent := ReplaceRegEx(FilePath, '.+\\(.+)\\.+', '$1', False, True); | Parent := ReplaceRegEx(FilePath, '.+\\(.+)\\.+', '$1', False, True); | ||
Line 205: | Line 282: | ||
<BR> | <BR> | ||
− | + | You can also use Meta Tags to extract e.g. the parent folder: | |
− | |||
<source> | <source> | ||
ParentFolder := CalculateMetaTag(FilePath, ':File_FolderName:'); | ParentFolder := CalculateMetaTag(FilePath, ':File_FolderName:'); | ||
Line 217: | Line 293: | ||
<BR> | <BR> | ||
− | To split file name into parts at an delimiter we can use f.ex.: | + | File name |
+ | |||
+ | To split the <b>file name</b><BR> | ||
+ | into parts at an given delimiter<BR> | ||
+ | we can use f.ex.: | ||
E.g. for<BR> | E.g. for<BR> | ||
Line 252: | Line 332: | ||
</source> | </source> | ||
+ | To split an file name with regular expression you can use something like this:<BR> | ||
+ | Note that you have to adjust the RegEx by your needs, according to your real file names. | ||
+ | <source> | ||
+ | var | ||
+ | Parts: TStringsArray; | ||
+ | begin | ||
+ | Parts := SubMatchesRegEx(WideExtractBaseName(FileName), '(.)(.+_)(.+_)(.+)', FALSE); | ||
+ | If (Length(Parts) <=0) then exit; | ||
+ | |||
+ | FileName := WideUpperCase(Parts[0]) + Parts[1] + WideUpperCase(Parts[2]) + Parts[3] + WideExtractFileExt(FileName); | ||
+ | end. | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Here we are using RegEx and WideCopy() to split an string into parts.<BR> | ||
+ | <BR> | ||
+ | For an example file name like<BR> | ||
+ | "Dzenan Loncarevic - 2009 - 10 - Laura (Bonus).mp3"<BR> | ||
+ | our message will look like:<BR> | ||
+ | "Dzenan Loncarevic - 2009 - 10 - [[User:Stefan|Stefan]] Laura (Bonus).mp3" | ||
+ | <source> | ||
+ | var | ||
+ | Parts: TStringsArray; | ||
+ | Base, Part1, Part2: WideString; | ||
+ | begin | ||
+ | Base := WideExtractBaseName(FileName); | ||
+ | |||
+ | //Find last '-' by greedy RegEx: | ||
+ | Parts := SubMatchesRegEx(Base, '(.+-)(.+)', FALSE); | ||
+ | If (Length(Parts) <=0) then exit; | ||
+ | |||
+ | //Split file name into two: | ||
+ | Part1 := WideCopy( Base, 1 , Length(Parts[0]) ); | ||
+ | Part2 := WideCopy( Base, Length(Parts[0]) +1, 999 ); | ||
+ | |||
+ | WideShowMessage(Part1 + ' ~~~ ' + Part2 + WideExtractFileExt(FileName)); | ||
+ | end. | ||
+ | </source> | ||
<BR> | <BR> | ||
--------------------- | --------------------- | ||
<BR> | <BR> |
Revision as of 07:45, 18 August 2011
Find an overview of all build-in functions there >> File Name Utilities.
Here on this page we show you only the needed functions to extract parts
of the file name and how to use them in an PascalScript for ReNamer.
We like to show you this on an example file name
"C:\GreatGrand\GrandParent\ParentFolder\file.ext"
First, there are the always available variables 'FilePath' and 'FileName'
You don't have to declare ('var' / 'dim') or initialize ('var="";') this variables.
Just use them, they are always there for you.
Variable | provides |
---|---|
FilePath | C:\GreatGrand\GrandParent\ParentFolder\file.ext |
FileName | file.ext |
Use this e.g. like:
var
vExt: WideString;
begin
vExt := WideExtractFileExt(FilePath);
FileName := FileName + '.backup' + vExt;
end.
And there are this functions to extract parts:
Function | provides |
---|---|
WideExtractFilePath | C:\GreatGrand\GrandParent\ParentFolder\ |
WideExtractFileDir | C:\GreatGrand\GrandParent\ParentFolder |
WideExtractFileDrive | C:\ |
WideExtractFileName | file.ext |
WideExtractBaseName | file |
WideExtractFileExt | .ext (dot included) |
You can fill an variable with the extracted part first
Use this e.g. like:
var
vPath, vDir, vDrive, vName, vBase, vExt, vE: WideString;
vOUT: WideString;
begin
//extract the parts and store them into an var each:
vPath := WideExtractFilePath(FilePath);
vDir := WideExtractFileDir(FilePath);
vDrive := WideExtractFileDrive(FilePath);
vName := WideExtractFileName(FilePath);
vBase := WideExtractBaseName(FilePath);
vExt := WideExtractFileExt(FilePath);
// Test output as MsgBox:
vOUT := 'Default build-in vars:' + #13#10
+ 'FilePath >>> ' + FilePath + #13#10
+ 'FileName >>> ' + FileName + #13#10
+ #13#10
+ 'Extracted by using functions:' + #13#10
+ 'WideExtractFilePath >>> ' + vPath + #13#10
+ 'WideExtractFileDir >>> ' + vDir + #13#10
+ 'WideExtractFileDrive >>> ' + vDrive + #13#10
+ 'WideExtractFileName >>> ' + vName + #13#10
+ 'WideExtractBaseName >>> ' + vBase + #13#10
+ 'WideExtractFileExt >>> ' + vExt;
ShowMessage( vOUT );
end.
Or just use the function 'on the fly', without using an var first
Use this e.g. like:
begin
FileName := FileName + '_backup' + WideExtractFileExt(FilePath);
end.
But this functions didn't gave all possibilities to split an full path into all wanted parts.
You have to know how to handle this functions and/or use own code to achieve what you want.
Here are some code snippets for this issue:
First we show you an 'trick' seen by Denis:
Here we extract the path first "WideExtractFileDir(FilePath)"
and then extract the last part, which is normal the filename, but here the parent folder "WideExtractFileName(...)"
You can even use this trick more then once:
(Here for our example "C:\GreatGrand\GrandParent\ParentFolder\file.ext")
nested Functions | provides the folder |
---|---|
WideExtractFileName(WideExtractFileDir(FilePath)); | ParentFolder |
WideExtractFileName(WideExtractFileDir(WideExtractFileDir(FilePath))); | GrandParent |
WideExtractFileName(WideExtractFileDir(WideExtractFileDir(WideExtractFileDir(FilePath)))); | GreatGrand |
Use this like:
var
ParentFolder, GrandParent, GreatGrandParent: WideString;
begin
ParentFolder := WideExtractFileName(WideExtractFileDir(FilePath));
GrandParent := WideExtractFileName(WideExtractFileDir(WideExtractFileDir(FilePath)));
GreatGrandParent := WideExtractFileName(WideExtractFileDir(WideExtractFileDir(WideExtractFileDir(FilePath))));
FileName := GreatGrandParent + '-' + GrandParent + '-' + ParentFolder + '-' + FileName;
end.
Other tricks:
To get the extension without the dot use something like:
vExt := WideReplaceStr(WideExtractFileExt(FilePath), '.', '');
Or showing this as step by step:
vExt := WideExtractFileExt(FilePath);
vExt := WideReplaceStr( vExt, '.', '');
Here is an another way to get the name of an parent folder of an path
by splitting the path at the back slash into an array of 'Folders'.
We use
Folders: TStringsArray;
"Folders := WideSplitString( WideExtractFileDir(FilePath), at sign '\')"
to get the elements of such an path.
Then we can access each level of parent folders
by referring to the right element in the array.
Note that an array start counting at '0'
And if you try to access an array element that is not there,
you will get an error message "Exception: Out Of Range".
Again for our example "C:\GreatGrand\GrandParent\ParentFolder\file.ext"
there are 4 elements in the array, counting from '0' to '3'
Array level | provides |
---|---|
Folders[0] | C: |
Folders[1] | GreatGrand |
Folders[2] | GrandParent |
Folders[3] | ParentFolder |
If you not know how deep the folder hierarchy is, you may want to count from the right.
Therefor we can utilize the max. amount of elements in an array. We use the 'Length' attribute here.
"Length(Folders)" is '4'. But Folders[4] is for our example path "Out Of Range".
That is why we use "Length(Folders) -1" to get '3'.
So to get the last element in array use "Folders[ Length(Folders) -1 ]", which is here the same as "Folders[ 3 ]"
And so we can use '-1' (4 -1 = 3) till '-4' (4 -4 = 0) for our example path. (remember: we have 4 elements, from '0' to '3'.)
Array level | provides the folder |
---|---|
Folders[Length(Folders)-1] | ParentFolder |
Folders[Length(Folders)-2] | GrandParent |
Folders[Length(Folders)-3] | GreatGrand |
Folders[Length(Folders)-4] | C: |
Use this like:
var
Folders: TStringsArray;
oldPath, ParentFolder, GrandParentFolder, GrandGrandParentFolder, TopMostFolder, SecondTopMostFolder: WideString;
begin
// Get parts of the current file path:
oldPath := WideExtractFileDir(FilePath);
Folders := WideSplitString(oldPath, '\');
TopMostFolder := Folders[1];
SecondTopMostFolder := Folders[2];
GrandGrandParentFolder := Folders[Length(Folders)-3];
GrandParentFolder := Folders[Length(Folders)-2];
ParentFolder := Folders[Length(Folders)-1];
FileName := SecondTopMostFolder + '-' + GrandParentFolder + '-' + ParentFolder + '-' + FileName;
end.
Tip:
You can use ShowMessage() like MsgBox to be prompte what the elements contains:
ShowMessage('Debug: ' + Folders[1] + ' # ' + Folders[Length(Folders)-1] );
To loop trough each element of an part (e.g. to check if an given folder exists)
you may take an look at this example:
var
I: Integer; Parts: TStringsArray;
begin
//function WideSplitString(const Input, Delimiter: WideString): TStringsArray;
Parts := WideSplitString(FilePath, '\');
for I:=0 to Length(Parts)-1 do
begin
// access each part via Parts[i]
end;
end.
And you could use Regular Expression to extract the parts of an part:
Parent := ReplaceRegEx(FilePath, '.+\\(.+)\\.+', '$1', False, True);
GrandPa := ReplaceRegEx(FilePath, '.+\\(.+)\\.+\\.+', '$1', False, True);
GrandGrandPa := ReplaceRegEx(FilePath, '.+\\(.+)\\.+\\.+\\.+', '$1', False, True);
But note that RegEx is slow by its nature. But then you will see this first for more then thousand files ;-)
You can also use Meta Tags to extract e.g. the parent folder:
ParentFolder := CalculateMetaTag(FilePath, ':File_FolderName:');
See 'Insert' Rule and click there at 'Insert Meta Tag'
File name
To split the file name
into parts at an given delimiter
we can use f.ex.:
E.g. for
FROM:
"my fav artist - title album song.mp3"
TO:
"My Fav Artist - Title album song.mp3"
Use:
We split the file name at the dash and then modify the case different for the part before, and the part after the dash.
var
Delimiter, Extension, Part1, Part2, Part2Char1, Part2Rest: WideString;
PosOfDelimiter: Integer;
begin
Delimiter := '-';
PosOfDelimiter := Pos(Delimiter, FileName);
if (PosOfDelimiter > 0) then
begin
Extension := WideExtractFileExt(FileName)
Part1 := WideCopy(WideExtractBaseName(FileName), 1, PosOfDelimiter -2 );
Part2 := WideCopy(WideExtractBaseName(FileName), PosOfDelimiter +2, Length(FileName) );
Part2Char1 := WideCopy(Part2, 1, 1 );
Part2Rest := WideCopy(Part2, 2, Length(Part2) -1 );
//ShowMessage('Debug: #' + Part1 + '#' + Part2 + '#' + Part2Char1 + '#' + Part2Rest + '#');
FileName := WideCaseCapitalize(Part1)
+ ' ' + Delimiter + ' '
+ WideUpperCase(Part2Char1) + WideLowerCase(Part2Rest)
+ WideUpperCase(Extension);
end;
end.
To split an file name with regular expression you can use something like this:
Note that you have to adjust the RegEx by your needs, according to your real file names.
var
Parts: TStringsArray;
begin
Parts := SubMatchesRegEx(WideExtractBaseName(FileName), '(.)(.+_)(.+_)(.+)', FALSE);
If (Length(Parts) <=0) then exit;
FileName := WideUpperCase(Parts[0]) + Parts[1] + WideUpperCase(Parts[2]) + Parts[3] + WideExtractFileExt(FileName);
end.
Here we are using RegEx and WideCopy() to split an string into parts.
For an example file name like
"Dzenan Loncarevic - 2009 - 10 - Laura (Bonus).mp3"
our message will look like:
"Dzenan Loncarevic - 2009 - 10 - Stefan Laura (Bonus).mp3"
var
Parts: TStringsArray;
Base, Part1, Part2: WideString;
begin
Base := WideExtractBaseName(FileName);
//Find last '-' by greedy RegEx:
Parts := SubMatchesRegEx(Base, '(.+-)(.+)', FALSE);
If (Length(Parts) <=0) then exit;
//Split file name into two:
Part1 := WideCopy( Base, 1 , Length(Parts[0]) );
Part2 := WideCopy( Base, Length(Parts[0]) +1, 999 );
WideShowMessage(Part1 + ' ~~~ ' + Part2 + WideExtractFileExt(FileName));
end.