Script iteration over a file/folder list

Features wanted...
Post Reply
Ash
Posts: 8
Joined: 24 Nov 2009 12:40

Script iteration over a file/folder list

Post by Ash »

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.

admin
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

Post by admin »

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...

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script iteration over a file/folder list

Post by Stefan »

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

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.

Ash
Posts: 8
Joined: 24 Nov 2009 12:40

Re: Script iteration over a file/folder list

Post by Ash »

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.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script iteration over a file/folder list

Post by Stefan »

I just edit my post due an another scripting idea:

$array = $array . <curname> . "|";
sel +1;
}
selfilter $array;

Pagat
Posts: 306
Joined: 09 Oct 2007 21:23
Location: Austria

Re: Script iteration over a file/folder list

Post by Pagat »

Stefan wrote:I just edit my post due an another scripting idea:
$array = $array . <curname> . "|";
sel +1;
}
selfilter $array;
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:

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, '#', '[#]';

Ash
Posts: 8
Joined: 24 Nov 2009 12:40

Re: Script iteration over a file/folder list

Post by Ash »

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).

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;

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script iteration over a file/folder list

Post by Stefan »

Hi Ash,
i don't tested this, but it looks like you enjoy XY and scripting :lol: ...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;
   }

admin
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

Post by admin »

Added <cursize>. :)

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script iteration over a file/folder list

Post by Stefan »

admin wrote:Added <cursize>. :)
Ehmm :shock: - thanks :D

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Script iteration over a file/folder list

Post by Stefan »

admin wrote:Added <cursize>. :)

Works :lol: 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";}


admin
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

Post by admin »

POC? Piece Of Cake?

Pagat
Posts: 306
Joined: 09 Oct 2007 21:23
Location: Austria

Re: Script iteration over a file/folder list

Post by Pagat »

maybe "Proof of Concept"? But to do it with XY is always a piece of cake :)

Post Reply