The new FindRepl.bat version 2.2 was released.
FindRepl.bat program provide a wide range of different uses because the possible ways that its parameters can be combined, although the large number of combinations may lead to some misunderstandings. For example, the capability of replace text in a block of lines selected by line numbers was already programmed in FindRepl.bat program since the first version indeed, but until I tried to add this capability I realized that the way to use it was by inserting a null search text (""), so I just
removed a test on this point in order to make this feature operational!. This way, this feature is not a "new" one nor a bug fix, so just an update in the documentation was required.
A similar point happens with the new /J switch in FindRepl version 2. The inclusion of this switch modifies the way that other parameters are processed (as JScript expressions instead of text), but
which parameters exactly should be affected by /J switch? The obvious one was the sReplace text, but there are more parameters in FindRepl program. The three "search" parameters (rSearch, rEndBlk and rBlock) are regular expressions so they are not affected by the /J switch, although the inclusion of /J eliminate the previous restriction in /A switch that rSearch was limited to contain just literal strings.
The last possible parameter is /S:sSource, that provide the text to be processed instead of Stdin file, and in this case the conclusion is obvious: when /J switch is included, the sSource text must be evaluated as a JScript expression that will provide the actual input text to process. Although this is a very small change in the code (just an additional "eval" function is needed indeed), the possibilities derived from this change are substantial; this way, this "not-new" feature increases one more time the range of possible problems that FindRepl.bat program may solve using the same concepts and methods than before.
When /J switch was added, several predefined functions were included in FindRepl version 2.1 in order to be used in the sReplace JScript expression, so this time we need to include some "data generating" functions designed to be used in the /S:sSource JScript expression. These additional predefined functions should belong to the same FindRepl version 2.1, not to a new version; however, the amount of added code is somewhat large, so I named it Version 2.2 although strictly speaking there is not any "new" feature on it.
The FindRepl.bat program listing placed in the first post of this thread now includes the additional code as usual, and the
documentation of Version 2 was modified in order to present the new predefined functions in a more organized way. I did a few minor changes in the names of some original functions so they fits better in the new organization. I suggest you to review the "3. FindRepl.bat predefined functions" section, specially the point "3.4. Data generating functions". Below there are a few examples of these functions.
- Example of the input of a prefilled form via prompt function:
Code: Select all
C:\> echo NAME's favorite color is COLOR and favorite pets are PETS. | FindRepl "NAME|COLOR|PETS" "prompt('Enter your '+$0+': ')" /J
Enter your NAME: Antonio
Enter your COLOR: green
Enter your PETS: dogs
Antonio's favorite color is green and favorite pets are dogs.
- List files that were modified more than 30 days ago and size larger than 1 MB, and allows the user to selectively delete them:
Code: Select all
dir /B | FindRepl "([^\r\n]*)\r\n" "(days(fileProperty($1,TW))>30)&&(fileProperty($1,Z)>1048576)?prompt('Delete '+$1+'? ').substr(0,1).toUpperCase()=='Y'?Delete($1)+'\r\n':'':''" /J
- Some examples taken from (http:
//www.dostips.com/forum/viewtopic.php?f=3&t=6081):
1) Convert all .txt files to lower case in the current directory:
Code: Select all
dir /B | FindRepl "([^\r\n]*)\r\n" "fileRename($1,$1.toLowerCase())" /J
2) Rename all 76 ".jpg" files in current directory to an increasing padded number followed by a constant string. Resulting file names should look like "01_Christmas2014.jpg", "02_Christmas2014.jpg", etc.:
Code: Select all
dir /B *.jpg | FindRepl "([^\r\n]*)\r\n" "/VAR:Num=100" "fileRename($1,(++Num).toString().substr(1)+'_Christmas2014.jpg')+'\r\n'" /J
- List all drives in the system and warn when the percentage of occupied space in a disk is greater than 85%:
Code: Select all
set "source=drivesCollection('Path','FreeSpace','TotalSize')"
set "search=#([^#]*)#,#([^#]*)#,#([^#]*)#\r\n"
FindRepl /S:=source /Q:# =search "$1+'\t'+(S=Math.floor(100-$2*100/$3))+'% Occupied'+(S>85?'\tRequires cleanup!':'')+'\r\n'" /J
- List all files in current folder with Created, Accessed and Modified Dates:
Code: Select all
FindRepl "/S:filesCollection('.','DateCreated','DateLastAccessed','DateLastModified','Name')" /J
- List the Path of all subfolders in current folder, including the Name of all files in each subfolder:
Code: Select all
FindRepl "/S:foldersCollection('.','Path','filesCollection(folder.Files,\'Name\')')" /J
- List the Path of all subfolders in current folder and all nested subfolders under them, but no more than two levels down:
Code: Select all
FindRepl "/VAR:Levels=2" "/S:foldersCollection('.','Path','Levels?(--Levels,folder.SubFolders):false','++Levels')" /J
- List the folders I have defined in My Documents:
Code: Select all
FindRepl "/S:specialFolders('MyDocuments.SubFolders','Name')" /J
- List the name of all Fonts installed in the system with .FNT extension:
Code: Select all
FindRepl "/S:specialFolders('Fonts.Files','Name')" /J ".*\.FNT"
- List the services installed in the system and its status:
Code: Select all
FindRepl "/S:wmiCollection('Win32_Service','Name','ServiceType','Started','State')" /J
As said before, it is important to understand the different ways that FindRepl's parameters may be combined in order to get a desired result. Let's review some possibilities.
If the rSearch argument is null, all input lines are just copied to the screen:
Code: Select all
C:\ type test.txt
This is just a small example of a
text file that
have three total lines.
C:\ type test.txt | FindRepl ""
This is just a small example of a
text file that
have three total lines.
You may let FindRepl to get all input lines, but show nothing this way:
Code: Select all
C:\ type test.txt | FindRepl ".|\n*" "" /J
The input lines are stored in a long string called "inputLines", that may be shown via the /L switch after all lines has been "processed":
Code: Select all
C:\ type test.txt | FindRepl ".|\n*" "" /J /L:inputLines
This is just a small example of a
text file that
have three total lines.
This way, you may apply any JScript extra function or method to the input lines in the /L expression, for example:
Code: Select all
C:\ type test.txt | FindRepl ".|\n*" "" /J /L:inputLines.toUpperCase()
THIS IS JUST A SMALL EXAMPLE OF A
TEXT FILE THAT
HAVE THREE TOTAL LINES.
Do you want to sort the input lines? Just split the string in individual lines (into an array), sort the array, and join the elements back in a string:
Code: Select all
C:\ type test.txt | FindRepl ".|\n*" "" /J /L:inputLines.split('\r\n').sort().join('\r\n')
This is just a small example of a
have three total lines.
text file that
Ops! The default JScript's sort method is case sensitive! The JScript documentation indicate that sort method may have a parameter that specify "The name of a function with two arguments used to determine the order of the elements, that must return one of the following values: A negative value if the first argument passed is less than the second argument. Zero if the two arguments are equivalent. A positive value if the first argument is greater than the second argument". That is:
Code: Select all
C:\ type test.txt | FindRepl ".|\n*" "" /J "/L:inputLines.split('\r\n').sort(function(a,b){var A=a.toUpperCase(),B=b.toUpperCase();return(A<B?-1:A>B?1:0)}).join('\r\n')"
have three total lines.
text file that
This is just a small example of a
This way, you may adjust the sort comparison exactly as you need it in order to solve your problem: start at a given column, left-fill a field with zeros, or any other requirement you may have in the same way than you adjust the rest of FindRepl parameters in order to get the result you want. FindRepl.bat program is a tool that may be as powerful as you want to use it.
The number of different results that may be obtained via the combination of FindRepl.bat Version 2.2 parameters and its predefined functions is large, so the types of possible results can not be easily anticipated. I found surprised myself when I realized that a certain combination may lead to a new type of result! It is necessary to perform several additional tests and, after that, post the examples of the new types of problems that may be solved using a certain combination of parameters in FindRepl.bat Version 2.2.
Antonio
PS - Below is the listing created by FComp /Modifications program that allows you to roll back from FindRepl.bat Version 2.2 to Version 2.1, as described at
this post.
V2.2_rollbackto_V2.1.txt:Code: Select all
20 -2 +1
21: rem Two new sets of predefined functions for Date and File management.
28 -1 +1
50: /J[:n] Specifies that rSearch/sReplace have expressions (regexp/JScript).
10 -3 92 -12 +5
153: See also Topic 2- Sections 3. and 4. on predefined functions.
154:
155: 7- FileSystemObject File object documentation:
156: Describe the properties that may be used in fileProperty
157: and the other four File management predefined functions.
13 -3 +1
171: "http://msdn.microsoft.com/en-us/library/1ft05taf(v=vs.84).aspx"
13 -1 +1
185: echo - Help on topic %choice% opened...
12 +4
198:
199: // PARSE PARAMETERS
200:
201:
21 -1 27 -5 +6
250: // Predefined variables
251:
252: if ( block=options.Item("VAR") ) eval ( "var "+block+";" );
253: if ( Jexpr) {
254: var JexprN = 10;
255: if ( options.Item("J") ) JexprN = parseInt(options.Item("J"));
8 -1 +1
264: // Predefined functions
42 -2 37 -4 4 -16 5 -2 +1
353: daysNow = Math.floor((new Date()).getTime()/millisecsPerDay);
11 -4 +2
365: function fileExist(fileName) {
366: return(fso.FileExists(fileName));
2 -220 +23
369: function fileCopy(fileName,destination) {
370: file = fso.GetFile(fileName);
371: file.Copy(destination);
372: return('File "'+fileName+'" copied');
373: }
374: function fileMove(fileName,destination) {
375: file = fso.GetFile(fileName);
376: file.Move(destination);
377: return('File "'+fileName+'" moved');
378: }
379: function fileDelete(fileName) {
380: file = fso.GetFile(fileName);
381: file.Delete();
382: return('File "'+fileName+'" deleted');
383: }
384:
385: var A = "Attributes", TC = "DateCreated", TA = "DateLastAccessed", TW = "DateLastModified",
386: D = "Drive", N = "Name", P = "ParentFolder", F = "Path", SN = "ShortName",
387: SF = "ShortPath", Z = "Size", X = "Type";
388: function fileProperty(fileName,property) {
389: file = fso.GetFile(fileName);
390: return( eval("file."+property) );
391: }
9 -3 10 -1 2 -1 +1
413: if ( alternation ) replace += sepOut+block[1];
47 -1 +1
461: repl[eval('"'+searchA[i]+'"')] = replaceA?eval('"'+replaceA[i]+'"'):"";
56 -1 17 -1 3 -14 +6
538: var inputLines = new Array(), lastLine = 1;
539: inputLines[0] = source;
540: procLines = true;
541: } else { // Process Stdin file
542:
543: inputLines = WScript.StdIn.ReadAll();
40 -1 +1
584: // endif Process Stdin file
108 -8 +7
693: if ( Jexpr && (lastLine=options.Item("L")) ) {
694: if ( lastLine.substr(0,1) == '=' ) lastLine = env(lastLine.substr(1));
695: if ( quote != undefined ) lastLine = lastLine.replace(eval("/"+quote+"/g"),"\\x22");
696: WScript.Stdout.WriteLine( eval(lastLine) );
697: }
698:
699: }
1