Page 1 of 1
Sort files depending on chars in filename
Posted: 15 Oct 2008 21:40
by ivan
My task is as follows: I have lots of files of different types in a folder and I need them sorting into appropriate folders (in the same branch of the tree) depending on what strings are present in the file names. My thoughts have instinctively turned to scripting, but after spending a considerable amount of time searching through the Help file and Wiki I only have one potentially possible solution.
Here is a rough outline:
1. Loop through the list of files one at a time
2. Use stringpos to find whether a defined string is present.
3. Then use eval() to determine whether stringpos found that string.
4. If it did then use moveto to move that file to the right folder.
5. Start all over from the top.
I have a couple of concerns: most importantly, is something like that currently possible or am I dreaming? also, how would I make the transition between 3 and 4, i.e. will the following work ($a is the result of stringpos):
Code: Select all
eval($a) = 1;
moveto RELATIVE_PATH, <curitem>;
The important aspect is that the above should only be executed if the eval($a) is true.
Thank you for your help in advance.
Re: Sort files depending on chars in filename
Posted: 15 Oct 2008 22:31
by jacky
You don't need eval here, just use a ternary with for example sub to call the script to move the file only when the string has been found. Something like this:
Code: Select all
strpos $p, <curitem>, "toto";
sub ($p > -1) ? "_moveFile" : "_nothing";
Then all you need is a script _moveFile with the code to move your file when the string has been found, and an empty script _nothing that does absolutely nothing
To loop though items, you might wanna look
over here for examples on how it can be done... (and you can even use getinfo & get ride of the use of clipboard now!)
Re: Sort files depending on chars in filename
Posted: 16 Oct 2008 01:15
by ivan
Thank you for providing help there jacky! I have tried to use your guidance and this is what I came up with:
Code: Select all
"Sorting"
// this script file
self $me, file;
// Item Name(s)
focus l;
#102;
// locate CRLF (when multiple items are selected)
strpos $p, <clipboard>, <crlf>;
// there's one, will do nothing
regexreplace $script, $script, "^[0-9]+$", 'incr $void;';
// no CRLF, only one item, let's add a CRLF as we require each line to end with one
regexreplace $script, $script, '^((?!^incr \$void;$).)*$', "copytext '<br>', a;";
// execute
load $script,,s;
// now turn the list of all items<crlf> into a little script
regexreplace $script, <clipboard>, "(.+)\r\n", " copytext ""$1""; load ""$me"", ""_ForEachItem""; ";
// and go
load $script,,s;
// clean
self $path, path;
strpos $p, <curitem>, "temp";
sub ($p > -1) ? "_moveFile" : "_nothing";
"_moveFile"
// item name
set $item, <clipboard>;
// select the item
sel 1,0;
sel "[$item]", backupto "D:\temp";
"_nothing"
However, I get the following error message: "Command 'load' called with empty 'resource' argument" and the script keeps recursing without actually copying the file to the directory specified. Can you please point me where I have made a mistake in the code? As usual, I will be most grateful

Re: Sort files depending on chars in filename
Posted: 16 Oct 2008 20:08
by jacky
Well, I'm not really sure what you're trying to do here to be honest, but here's something that should work, or help you I hope:
Code: Select all
"To All Selected Items... : ForEachItem"
// this script file
self $me, file;
// now turn the list of all selected items into a little script
regexreplace $script, getinfo("SelectedItemsPathNames", <crlf>), "(.+)\r\n", " copytext ""$1""; load ""$me"", ""_ForEachItem_moving""; ";
// and execute it
load $script,,s;
"_ForEachItem_moving"
// extract item's name
regexreplace $item, <clipboard>, "^.+\\(.+)$", "$1";
//
strpos $p, $item, "temp";
sub ($p > -1) ? "_moveFile" : "_nothing";
"_moveFile"
moveto "d:\dest\", <clipboard>;
"_nothing"
Re: Sort files depending on chars in filename
Posted: 16 Oct 2008 20:39
by ivan
jacky wrote:Well, I'm not really sure what you're trying to do here to be honest, but here's something that should work, or help you I hope
Thank you again for help. I am trying to move a file to a special folder depending on strings in the filename. For example, if I have a file which has "temp" in the name then it will be moved to a folder called "Temp" and so on. I think the script that you have provided is almost perfect, but how do I expand it to include more string-folder combinations within just that script?
P.S. Also, when calling this command
this error message shows up
Code: Select all
Command 'load' called with empty 'resource' argument.
load
_ForEachItem_moving
Re: Sort files depending on chars in filename
Posted: 16 Oct 2008 22:02
by jacky
Well, in _ForEachItem_moving you could just add as many tests as you'd like, or determine the destination folder and save it (e.g. to a tmp.ini using setkey) and then use that on _moveFile, probably many other ways as well, you'll just have to see what suits you best.
About the error you reported, I'm guessing it's probably because you're not using a script file, and as I said on the post about this ForEachItem script, it needs to be a script file in order to work...
Re: Sort files depending on chars in filename
Posted: 16 Oct 2008 22:39
by ivan
So I have this in my UDC menu:
Code: Select all
"To All Selected Items... : ForEachItem"
// this script file
self $me, file;
// now turn the list of all selected items into a little script
regexreplace $script, getinfo("SelectedItemsPathNames", <crlf>), "(.+)\r\n", " copytext ""$1""; load ""$me"", ""_ForEachItem_moving""; ";
// and execute it
load $script,,s;
and in my Scripts folder I have a file called "_ForEachItem_moving.xys" that has this code:
Code: Select all
"_ForEachItem_moving"
// extract item's name
regexreplace $item, <clipboard>, "^.+\\(.+)$", "$1";
//
strpos $p, $item, "temp";
sub ($p > -1) ? "_moveFile" : "_nothing";
"_moveFile"
moveto "d:\temp\", <clipboard>;
"_nothing"
yet it's still complaining about the empty resource argument

Re: Sort files depending on chars in filename
Posted: 16 Oct 2008 23:14
by jacky
Of course it does, both ForEachItem and _ForEachItem_moving have to do in the same script file (same goes for _moveFile & _nothing as it's done now). If you want to use this from UDC, use category Load Script File
Re: Sort files depending on chars in filename
Posted: 16 Oct 2008 23:48
by ivan
jacky wrote:Of course it does, both ForEachItem and _ForEachItem_moving have to do in the same script file (same goes for _moveFile & _nothing as it's done now). If you want to use this from UDC, use category Load Script File
Now I'm completely lost. I've created 2 XYS files (code below), put them in the Scripts folder, assigned a KS to ForEachItem.xys and it still doesn't work, just recurses over and over without touching the other XYS file.
ForEachItem.xys
Code: Select all
"To All Selected Items... : ForEachItem"
// this script file
self $me, file;
// now turn the list of all selected items into a little script
regexreplace $script, getinfo("SelectedItemsPathNames", <crlf>), "(.+)\r\n", " copytext ""$1""; load ""$me"", ""_ForEachItem_moving""; ";
// and execute it
load $script,,s;
"_ForEachItem_moving"
// extract item's name
regexreplace $item, <clipboard>, "^.+\\(.+)$", "$1";
//
strpos $p, $item, "temp";
sub ($p > -1) ? "_moveFile" : "_nothing";
_moveFile.xys
Code: Select all
"_moveFile"
moveto "d:\temp\", <clipboard>;
"_nothing"
Re: Sort files depending on chars in filename
Posted: 17 Oct 2008 00:10
by jacky
ivan wrote:Now I'm completely lost. I've created 2 XYS files (code below), put them in the Scripts folder, assigned a KS to ForEachItem.xys and it still doesn't work, just recurses over and over without touching the other XYS file.
Yeah, I guess I wasn't really clear on that one... sorry. I meant to say both _moveFile & _nothing have to be in the same file as the other scripts. Put everything in one file and it should work.
Re: Sort files depending on chars in filename
Posted: 17 Oct 2008 00:17
by ivan
jacky wrote:Yeah, I guess I wasn't really clear on that one... sorry. I meant to say both _moveFile & _nothing have to be in the same file as the other scripts. Put everything in one file and it should work.
Fantastic and you're right, it does. So now if I want to have another string-folder combination then I'll just add this segment just above "nothing", correct?
Code: Select all
"_ForEachItem_moving"
// extract item's name
regexreplace $item, <clipboard>, "^.+\\(.+)$", "$1";
//
strpos $p, $item, "WHATEVER";
sub ($p > -1) ? "_moveFile" : "_nothing";
"_moveFile"
moveto "DESTINATION", <clipboard>;
EDIT:
I figured it out!
Final script code:
Code: Select all
"To All Selected Items... : ForEachItem"
// this script file
self $me, file;
// now turn the list of all selected items into a little script
regexreplace $script, getinfo("SelectedItemsPathNames", <crlf>), "(.+)\r\n", " copytext ""$1""; load ""$me"", ""_ForEachItem_moving""; ";
// and execute it
load $script,,s;
"_ForEachItem_moving"
// extract item's name
regexreplace $item, <clipboard>, "^.+\\(.+)$", "$1";
//
strpos $p, $item, "temp";
sub ($p > -1) ? "_moveFile" : "_nothing";
strpos $p, $item, "try2";
sub ($p > -1) ? "_moveFile2" : "_nothing";
"_moveFile"
moveto "d:\temp\", <clipboard>;
"_moveFile2"
moveto "d:\temp2\", <clipboard>;
"_nothing"
and for each new string-folder combo i need to add a couple of lines of code for strpos and sub and for moving the file. Thank you jacky!

Re: Sort files depending on chars in filename
Posted: 20 Oct 2008 13:16
by ivan
Ok Don, I may have unearthed a bug here, but whether it is or it's a "feature" you'll be able to tell.
To reproduce:
1. Load the script file below through your UDC menu and assign a KS to it:
Code: Select all
"To All Selected Items... : ForEachItem"
// this script file
self $me, file;
// now turn the list of all selected items into a little script
regexreplace $script, getinfo("SelectedItemsPathNames", <crlf>), "(.+)\r\n", " copytext ""$1""; load ""$me"", ""_ForEachItem_moving""; ";
// and execute it
load $script,,s;
"_ForEachItem_moving"
// extract item's name
regexreplace $item, <clipboard>, "^.+\\(.+)$", "$1";
//
strpos $p, $item, "temp.try";
sub ($p > -1) ? "_moveFile" : "_nothing";
strpos $p, $item, "temp";
sub ($p > -1) ? "_moveFile2" : "_nothing";
"_moveFile"
moveto "d:\temp\", <clipboard>;
"_moveFile2"
moveto "d:\temp2\", <clipboard>;
"_nothing"
2. Create a file called temp.try.txt
3. Create the necessary dirs for a file to be moved to
4. Try applying the script to that file
The problem seems to be that pattern matching mechanism goes through the whole list of patterns before moving a file to the correct folder (as opposed to going for the first match it finds). This creates a clash in our example, which pops up a warning window saying the file could not be found and that certain part of the script has failed. My actual script has some refined sorting at the top of it to prevent incorrect sorting, which is necessary because wildcards aren't allowed here, but I still get a warning. At the very least, it's strongly undesired behaviour and should not happen.
Re: Sort files depending on chars in filename
Posted: 20 Oct 2008 14:10
by jacky
ivan wrote:Ok Don, I may have unearthed a bug here, but whether it is or it's a "feature" you'll be able to tell.
hmm.. No there's no bug in XY at all here, it's your script that doesn't work as you'd like maybe, since you test each file for all "patterns". Nothing anyone but you can fix here...
Re: Sort files depending on chars in filename
Posted: 20 Oct 2008 14:34
by ivan
jacky wrote:hmm.. No there's no bug in XY at all here, it's your script that doesn't work as you'd like maybe, since you test each file for all "patterns". Nothing anyone but you can fix here...
Nah, I prefer to blame the tools instead of the workman
It appears evident that recursing through a list of items doesn't provide any sense of intuition and precedence. I specifically place the code that moves special items to a dedicated folder at the top of the script file so I'd expect it to be executed and override any code further down below. Once an item is extracted to clipboard and is consequently moved to appropriate folder, it should not be on clipboard any more, being there after the fact is redundant. After all, I'm moving it not copying it.