Script iteration over a file/folder list
Script iteration over a file/folder list
Would it be possible to add XYPlorerer script functions that allow us to iterate over the items in the current list?
A script version of the Win32 FindFirstFile / FindNextFile would be great. These functions could take a parameter indicating 'all files', 'selected files', 'unselected files' and would just return the full path of the next item (both files and folders). This path could then be passed to the other existing functions to get more information about the file/folder.
For example, I would then be able to write a script that iterates over say 1000 items in the current list (using a while loop) and selects all *.log items created before a certain date and with size greater that 100 MB. I could then use any of the existing functions that operate on selected items.
However, to support this is it possible to multi-select list items from a script? When iterating over items, the ability to set an item as selected, without un-selecting previously selected items, would be great.
The 'sel' and 'selfilter' functions don't seem to support this (multiple calls to 'selfilter' clear the previous selections).
I realise the existing Find Files window can do something similar, but having scripting functions supporting iteration and multiple selection would make this a very powerful feature.
A script version of the Win32 FindFirstFile / FindNextFile would be great. These functions could take a parameter indicating 'all files', 'selected files', 'unselected files' and would just return the full path of the next item (both files and folders). This path could then be passed to the other existing functions to get more information about the file/folder.
For example, I would then be able to write a script that iterates over say 1000 items in the current list (using a while loop) and selects all *.log items created before a certain date and with size greater that 100 MB. I could then use any of the existing functions that operate on selected items.
However, to support this is it possible to multi-select list items from a script? When iterating over items, the ability to set an item as selected, without un-selecting previously selected items, would be great.
The 'sel' and 'selfilter' functions don't seem to support this (multiple calls to 'selfilter' clear the previous selections).
I realise the existing Find Files window can do something similar, but having scripting functions supporting iteration and multiple selection would make this a very powerful feature.
-
- Site Admin
- Posts: 60602
- Joined: 22 May 2004 16:48
- Location: Win8.1 @100%, Win10 @100%
- Contact:
Re: Script iteration over a file/folder list
Conc. iteration, you can iterate over the current list using script commands getinfo , gettoken , and a while loop. There are examples in this forum I think.
Conc. the selecting without unselecting I added this just yesterday! Will upload beta version today...
Conc. the selecting without unselecting I added this just yesterday! Will upload beta version today...
FAQ | XY News RSS | XY Twitter
Re: Script iteration over a file/folder list
Hi Ash, welcome.
If you want you can read this post to learn how to start scripting => How did you start scripting?
Maybe you search for an framework like this:
// loop through the whole list
// loop through the whole list
Or to select the found files instead of showing them only:
An description of the commands you will find in the help or on the wiki.
If you want you can read this post to learn how to start scripting => How did you start scripting?
Maybe you search for an framework like this:
// loop through the whole list
Code: Select all
//sel 1;
while ( <curitem> != '' )
{
msg <curitem>;
sel +1;
}
// loop through the whole list
Code: Select all
sel 1;
$count=0;
$array="";
while ( <curitem> != '' )
{
IF ("<curext>"=="log")
{
//check size and date here...//
//msg <curitem>;
//store found items in an array:
$array = $array . <curitem> . <crlf>;
incr $count;
}
sel +1;
}
IF ($count > 0){ text $array; }else{msg "Nothing found";}
Or to select the found files instead of showing them only:
$array = $array . <curname> . "|";
incr $count;
}
sel +1;
}
IF ($count > 0){ selfilter $array; } else { msg "Nothing found"; }
An description of the commands you will find in the help or on the wiki.
Ash wrote:Would it be possible to add XYPlorerer script functions that allow us to iterate over the items in the current list?
A script version of the Win32 FindFirstFile / FindNextFile would be great. These functions could take a parameter indicating 'all files', 'selected files', 'unselected files' and would just return the full path of the next item (both files and folders). This path could then be passed to the other existing functions to get more information about the file/folder.
For example, I would then be able to write a script that iterates over say 1000 items in the current list (using a while loop) and selects all *.log items created before a certain date and with size greater that 100 MB. I could then use any of the existing functions that operate on selected items.
However, to support this is it possible to multi-select list items from a script? When iterating over items, the ability to set an item as selected, without un-selecting previously selected items, would be great.
The 'sel' and 'selfilter' functions don't seem to support this (multiple calls to 'selfilter' clear the previous selections).
I realise the existing Find Files window can do something similar, but having scripting functions supporting iteration and multiple selection would make this a very powerful feature.
Last edited by Stefan on 22 Jun 2010 08:35, edited 1 time in total.
Re: Script iteration over a file/folder list
Thanks for the quick responses, this really is a very helpful forum.
<curitem> combined with multiple selection capability (in the next version) should give me plenty to play with.
Thanks again.
<curitem> combined with multiple selection capability (in the next version) should give me plenty to play with.
Thanks again.
Re: Script iteration over a file/folder list
I just edit my post due an another scripting idea:
$array = $array . <curname> . "|";
sel +1;
}
selfilter $array;
Re: Script iteration over a file/folder list
Be careful with this as there are at least two characters that need special care in a selfilter command. Furthermore, to get an exact match on the filenames each of them should be quoted. From one of my scripts:Stefan wrote:I just edit my post due an another scripting idea:$array = $array . <curname> . "|";
sel +1;
}
selfilter $array;
Code: Select all
//Remove the "|" at the end
substr $itemlist, $itemlist, 0, -1;
//Quote all items in the list
replace $itemlist, quote($itemlist), '|', '"|"';
//Handle special characters like '[' and '#'
replace $itemlist, $itemlist, '[', '[[]';
replace $itemlist, $itemlist, '#', '[#]';
Re: Script iteration over a file/folder list
Thanks to the suggestions from Stefan, Donald and Pagat I've come up with the following script. I'm sure there are still bugs but it works quite well for me.
It uses the report command instead of manually incrementing the current selection. This improves the performance a bit over large lists (Thanks to Jacky on this post http://www.xyplorer.com/xyfc/viewtopic.php?f=7&t=4577 for mentioning the report() command).
It uses the report command instead of manually incrementing the current selection. This improves the performance a bit over large lists (Thanks to Jacky on this post http://www.xyplorer.com/xyfc/viewtopic.php?f=7&t=4577 for mentioning the report() command).
Code: Select all
// Use the report command with a custom template to store the list of all files in the current list
$files=report("{name}|{Created}|{Size RAW}|");
// $i is the counter used to pass to gettoken
$i=1;
// $selFiles will contain the list of file names (not including paths) that match the required filters.
// There is a feature (undocumented?) of the selfilter command that will automatically split on the | character
$selFiles="|";
while(TRUE)
{
// Format created by report command for each file is eg: |C:\Temp\testfile.txt|14/04/2010 09:34:20|12496|
$file=gettoken($files,$i,"|");
$i++;
$created=gettoken($files,$i,"|");
$i++;
$filesize=gettoken($files,$i,"|");
$i++;
//Msg $filesize;
// Exit loop when no more tokens
if ($file=='')
{
break;
}
// Perform required file extension, creation date and size checks
// Only files with extension .exe
if (strpos($file,".exe")==strlen($file)-4)
{
// Only files older than 30 days
if (datediff($created,,"d")>30)
{
// Only files of size greater than 1 million bytes
if ($filesize!='' && compare($filesize,"1000000","n")==1)
{
// This is a file of interest
$selFiles= $selFiles . $file . "|";
}
}
}
}
//Remove the "|" at the end
substr $selFiles, $selFiles, 0, -1;
//Quote all items in the list
replace $selFiles, quote($selFiles), '|', '"|"';
//Handle special characters like '[' and '#'
replace $selFiles, $selFiles, '[', '[[]';
replace $selFiles, $selFiles, '#', '[#]';
// Select all matching files in the current list
selfilter $selFiles;
Re: Script iteration over a file/folder list
Hi Ash,
i don't tested this, but it looks like you enjoy XY and scripting ...good work :thumpsup:
---
This give me new ideas how to use scripting, thank you.
But i must discover that scripting is missed "<cursize>"
and something like gettoken("size") to give the file size as amount of bytes.
I find this <...> easier to use then report()
@Don, Maybe its worth to implement this?
i don't tested this, but it looks like you enjoy XY and scripting ...good work :thumpsup:
---
This give me new ideas how to use scripting, thank you.
But i must discover that scripting is missed "<cursize>"
and something like gettoken("size") to give the file size as amount of bytes.
I find this <...> easier to use then report()
@Don, Maybe its worth to implement this?
Code: Select all
// loop through the whole list
while ( "<curitem>" != '' )
{
// Only files with extension .exe
IF ("<curext>"=="exe")
{
// Only files older than 30 days
IF (datediff("<datem>",,"d")>30)
{
// Only files of size greater than 1 million bytes
IF (compare("<cursize>","1000000","n")==1)
{
//Do something
}
}
}
sel +1;
}
Re: Script iteration over a file/folder list
Ehmm - thanksadmin wrote:Added <cursize>.
Re: Script iteration over a file/folder list
admin wrote:Added <cursize>.
Works thanks.
//Skip folders:
IF ("<cursize>" != "")
// Only files of size
IF (compare("<cursize>","4194304","n")==1)
Just an POC:
Code: Select all
//ToDo: run in background, no screen update
//ToDo: disable work with XY while script runs
//ToDo: no add $path to history
//ToDo: replace DIR /B/S by report()
//"create recursiv list"
run "%comspec% /c dir /B /S /AD > C:\Temp\xyDirList.txt";
wait 3000;
$pathS = readfile("C:\Temp\xyDirList.txt");
$pathS = <curpath><crlf>$pathS;
$pathscount=1;
$curPath = "<curpath>";
//Prevent scanning large directories
//$DirListSize = getinfo("size", "C:\Temp\xyDirList.txt");
goto "C:\Temp\";
selfilter "xyDirList.txt";
$DirListSize = replace(report("{Size B}",1),".");
goto $curPath;
//L<R = -1 / L==R=0 / L>R=1
end (compare( $DirListSize,"5000","n")==1), "Too large directory, will end now";
$count=0;
$array="";
$ExtensionsList = "exe"; // txt log bat ini cmd vbs js bak tmp old $$$ gid";
while (1)
{
$path = gettoken( $pathS, $pathscount, <crlf>);
If ($path==""){break;}
// OEM DOS to ANSI Win:
// on german Windows LocaleID: 1031, Default ANSI CodePage: 1252
$path = regexreplace( $path , chr(8222), chr(228));
$path = regexreplace( $path, chr(0381), chr(196));
$path = regexreplace( $path, chr(8221), chr(246));
$path = regexreplace( $path, chr(8482), chr(214));
$path = regexreplace( $path, chr(0129), chr(252));
$path = regexreplace( $path, chr(0353), chr(220));
$path = regexreplace( $path, chr(0225), chr(223));
Goto $path;
sel 1;
while ( <curitem> != '' )
{
//Skip folders:
//(For <cursize> you need the latest XYplorer BETA version v9.20.0007, 23-jun-2010)
IF ("<cursize>" != "")
{
// Only files with extension .exe
//IF ("<curext>"=="vbs")
//
//If current selected ext part of the ExtensionsList
IF (strpos($ExtensionsList ,"<curext>") != -1)
{
// Only files older than 30 days
IF (datediff("<datem>",,"d")>3)
{
// Only files of size greater than 4MB / 4.194.304 Bytes
// KB = 1.024 Byte
// MB = 1.048.576 Byte * 4 = 4.194.304
// GB = 1.073.741.824 Byte
IF (compare("<cursize>","4194304","n")==1)
{
$array = $array . "<curitem><crlf>";
incr $count;
}
}
}
}
sel +1;
}
$pathscount++
}
goto $curPath;
IF ($count > 0){ text $array;}else{msg "Nothing found";}
Re: Script iteration over a file/folder list
maybe "Proof of Concept"? But to do it with XY is always a piece of cake