Sort files depending on chars in filename

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
Post Reply
ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Sort files depending on chars in filename

Post 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.
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Sort files depending on chars in filename

Post 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!)
Proud XYplorer Fanatic

ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Re: Sort files depending on chars in filename

Post 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 :)
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Sort files depending on chars in filename

Post 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"
Proud XYplorer Fanatic

ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Re: Sort files depending on chars in filename

Post 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

Code: Select all

load "", "_ForEachItem_moving"
this error message shows up

Code: Select all

Command 'load' called with empty 'resource' argument.
load
_ForEachItem_moving
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Sort files depending on chars in filename

Post 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...
Proud XYplorer Fanatic

ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Re: Sort files depending on chars in filename

Post 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 :(
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Sort files depending on chars in filename

Post 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
Proud XYplorer Fanatic

ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Re: Sort files depending on chars in filename

Post 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"
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Sort files depending on chars in filename

Post 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.
Proud XYplorer Fanatic

ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Re: Sort files depending on chars in filename

Post 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! 8)
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Re: Sort files depending on chars in filename

Post 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.
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Sort files depending on chars in filename

Post 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...
Proud XYplorer Fanatic

ivan
Posts: 577
Joined: 02 Apr 2008 12:52
Contact:

Re: Sort files depending on chars in filename

Post 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 :P

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.
Windows Vista Business SP1 32-bit, Logitech MX400 mouse, SetPoint 4.60.122
Image

Post Reply