| Have you ever needed to perform search / | | | | InsStr 1 'set search='" >t$1.batecho %3| tcl |
| replace operations on multiple files in a folder and | | | | "ReplStr '#22' '' | InsStr 1 'set replace='" |
| all its subfolders? Have you ever needed to | | | | >>t$1.batcall t$1.bat |
| search / replace text in a list of files? How about | | | | These three magical lines simply remove the |
| carrying out multiple search / replace operations | | | | surrounding double-quotes from each of the |
| on a single file based on search / replace pairs | | | | search / replace parameters that are passed into |
| specified in a text file? This article shows how to | | | | ProcFile. Not that the parameters themselves are |
| do each of these common search / replace | | | | altered in any way. Their unquoted contents are |
| operations using TEXTools--and believe it or | | | | merely copied into environment variables! Note |
| not--in only 7 lines of batch code! | | | | again the use of an on-the-fly batch file to |
| To carry out each of these tasks, we'll be utilizing | | | | accomplish this. Laying down tracks... |
| TEXTools (TCL.exe) from a batch file. TEXTools | | | | So now, our ProcFile.bat looks something like this: |
| is the perfect compliment to batch file | | | | :: Remove any surrounding double-quotes from |
| programming as it greatly extends the power of | | | | the search/replace text...echo %2| tcl "ReplStr |
| batch files. Without implementing a single for loop, | | | | '#22' '' | InsStr 1 'set search='" >t$1.batecho |
| a TEXTools endowed batch file can nonetheless | | | | %3| tcl "ReplStr '#22' '' | InsStr 1 'set replace='" |
| easily process multiple files. This is made possible | | | | >>t$1.batcall t$1.bat |
| because batch files can be constructed on-the-fly | | | | :: Perform text replacements on this file...type %1 | |
| by another batch file and then called by that | | | | tcl "ReplStr '%search%' '%replace%'" |
| batch file, (its kind of like a train that builds its | | | | >t$1.txttype t$1.txt >%1 |
| track as it goes). The reason that a for loop isn't | | | | Bear in-mind that this is a bare-bones |
| needed here to process multiple files is simply | | | | implementation of ProcFile.bat. Normally, you'd |
| because TEXTools can take a list of files that | | | | include some logic to abort execution if all |
| need to be processed and translate that list into a | | | | parameters weren't supplied, etc. but this is just a |
| batch file that, when run, results in the processing | | | | demonstration. For the actual batch files, see the |
| of each of the files. For example, suppose we | | | | "Search and Replace" examples available in the |
| wanted to carry out some relatively complex | | | | TEXTools download package (installed beneath the |
| text editing operations on the following list of | | | | "Sample Scripts" folder) and also available online at |
| files:myfile.txtyourfile.txttheirfile.txt | | | | [ Now, on to bigger and better things... |
| ... | | | | Using a Recursive File Search |
| One way to do this would be to place the editing | | | | Now that we have a batch file that performs |
| logic into a batch file called procfile.bat and then | | | | text replacements on a single file, how can we |
| process each file--one after the other--using | | | | employ it to process all files in a given folder and |
| procfile.bat like this:procfile.bat myfile.txtprocfile.bat | | | | its subfolders? The key to this lies in the DIR |
| yourfile.txtprocfile.bat theirfile.txt | | | | command. When used with the /b and /s |
| ... | | | | switches, the DIR command lists (fully qualified) all |
| That's great if you only have 3 files, but what if | | | | files in a folder (and all its subfolders) that match a |
| you have 100 or even 1000 files to process? | | | | given file specification. Imagine that... a list of all the |
| That's where TEXTools comes into the picture. If | | | | files in a given folder and its subfolders that |
| batch files are just text and they can be | | | | match say, the file specification, "work*.txt"! In |
| constructed on-the-fly, then why not use | | | | practical terms that translates into a gem like |
| TEXTools to turn our list of filenames into a batch | | | | this:dir %1 /b /s | tcl "InsStr 1 'call ProcFile.bat #22' |
| file that, when run, results in the processing of | | | | | AppendStr '#22 %2 %3'" >t$2.batcall t$2.bat |
| each of the files? If a batch file like procfile.bat is | | | | Here's a batch file (say, "Recursive.bat") that can |
| going to be employed in the process anyway, | | | | be called as follows: |
| then we're already half-way to our goal. What we | | | | Recursive work*.txt "this" "that" |
| want is for the list of file names to be preceded | | | | Here, it would replace all instances of "this" with |
| by "procfile.bat" with one change--procfile.bat | | | | "that" in all files (in the current folder and |
| needs to be called. Now we have a batch file that | | | | subfolders) matching "work*.txt". Not bad for 7 |
| will do all the work for us:call procfile.bat | | | | lines of batch code, eh? |
| myfile.txtcall procfile.bat yourfile.txtcall procfile.bat | | | | Using a List of Files |
| theirfile.txt | | | | If the files to be edited are listed in a text file, the |
| ... | | | | batch code needed to process them is almost |
| Of course, this is the kind of thing that TEXTools | | | | identical to the above:type %1 | tcl "InsStr 1 'call |
| excels at doing. Adding the text, "call procfile.bat " | | | | ProcFile.bat #22' | AppendStr '#22 %2 %3'" |
| to the front of every line in a text file containing | | | | >t$2.batcall t$2.bat |
| hundreds of file names--in order to create and | | | | The only difference is in where the list of files |
| execute an on-the-fly batch file is a snap:type | | | | originates. With this approach, all you need is a list |
| ListOfFiles.txt | tcl InsStr 1 'call procfile.bat ' | | | | of files in a text file to process. Such a batch file |
| >t$1.batcall t$1.bat | | | | might be called like this: |
| We're now ready to tackle our assignment | | | | ProcFileList FileList.txt "this" "that" |
| except for one missing puzzle piece. We need our | | | | This would replace all instances of "this" with "that" |
| procfile.bat. Ours needs to take as arguments a | | | | in all of the files listed in FileList.txt. |
| file name, a search text and a replacement text: | | | | Using a List of Replacements |
| ProcFile | | | | This last example of search and replace performs |
| Internally, ProcFile.bat will edit the given file by | | | | multiple edits on a single file by utilizing a file |
| replacing all occurrences of with inside the file. | | | | containing multiple search / replace pairs. Again, a |
| Fundamentally, this could be done with just two | | | | call to ProcFile is all that is needed:type %2 | tcl |
| lines of code (under Windows 95 and 98, etc. this | | | | "InsStr 1 'call ProcFile.bat %1 '" >t$2.batcall |
| could be done in a single line without the need of | | | | t$2.bat |
| a temporary intermediate file):type %1 | tcl | | | | Such a batch file as this might be called |
| "ReplStr '%2' '%3'" >t$1.txttype t$1.txt >%1 | | | | ProcReplList.bat. Here's how it would be called to |
| In reality, we need a bit more than this though. | | | | perform multiple search / replacement operations |
| What if the search text or replacement text is | | | | on MyFile.txt using the search / replace pairs |
| specified having embedded blanks? This can only | | | | found in Replacements.txt: |
| be done at the command prompt by using | | | | ProcReplList MyFile.txt Replacements.txt |
| surrounding double-quotes like so: | | | | Note: Each of the above search / replace |
| ProcFile myfile.txt "red car" "blue car" | | | | examples can be found online at [ or inside the |
| The problem is that these surrounding | | | | TEXTools download package, (installed beneath |
| double-quotes are part of the parameter as far | | | | the "Sample Scripts" folder). |
| as Windows is concerned. As far as we're | | | | Permission is granted to freely post or distribute |
| concerned however, they're not and so we must | | | | this article so long as it is unedited and credit and |
| get rid of them. Again, this is a simple matter | | | | copyright information is left intact. |
| using TEXTools:echo %2| tcl "ReplStr '#22' '' | | | | | |