Search and Replace Text in Multiple Files in Only 7 Lines

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 aboutThese three magical lines simply remove the
carrying out multiple search / replace operationssurrounding double-quotes from each of the
on a single file based on search / replace pairssearch / replace parameters that are passed into
specified in a text file? This article shows how toProcFile. Not that the parameters themselves are
do each of these common search / replacealtered in any way. Their unquoted contents are
operations using TEXTools--and believe it ormerely 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 utilizingaccomplish this. Laying down tracks...
TEXTools (TCL.exe) from a batch file. TEXToolsSo 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 ofthe 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 thattcl "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'tBear in-mind that this is a bare-bones
needed here to process multiple files is simplyimplementation of ProcFile.bat. Normally, you'd
because TEXTools can take a list of files thatinclude some logic to abort execution if all
need to be processed and translate that list into aparameters weren't supplied, etc. but this is just a
batch file that, when run, results in the processingdemonstration. 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 complexTEXTools 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 editingNow that we have a batch file that performs
logic into a batch file called procfile.bat and thentext replacements on a single file, how can we
process each file--one after the other--usingemploy it to process all files in a given folder and
procfile.bat like this:procfile.bat myfile.txtprocfile.batits subfolders? The key to this lies in the DIR
yourfile.txtprocfile.bat theirfile.txtcommand. 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 iffiles 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. Iffiles in a given folder and its subfolders that
batch files are just text and they can bematch say, the file specification, "work*.txt"! In
constructed on-the-fly, then why not usepractical terms that translates into a gem like
TEXTools to turn our list of filenames into a batchthis: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 isHere'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 weRecursive work*.txt "this" "that"
want is for the list of file names to be precededHere, 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 thatsubfolders) matching "work*.txt". Not bad for 7
will do all the work for us:call procfile.batlines of batch code, eh?
myfile.txtcall procfile.bat yourfile.txtcall procfile.batUsing a List of Files
theirfile.txtIf 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 TEXToolsidentical 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 andThe only difference is in where the list of files
execute an on-the-fly batch file is a snap:typeoriginates. 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.batmight be called like this:
We're now ready to tackle our assignmentProcFileList FileList.txt "this" "that"
except for one missing puzzle piece. We need ourThis would replace all instances of "this" with "that"
procfile.bat. Ours needs to take as arguments ain all of the files listed in FileList.txt.
file name, a search text and a replacement text:Using a List of Replacements
ProcFileThis last example of search and replace performs
Internally, ProcFile.bat will edit the given file bymultiple 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 twocall 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 oft$2.bat
a temporary intermediate file):type %1 | tclSuch a batch file as this might be called
"ReplStr '%2' '%3'" >t$1.txttype t$1.txt >%1ProcReplList.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 ison MyFile.txt using the search / replace pairs
specified having embedded blanks? This can onlyfound in Replacements.txt:
be done at the command prompt by usingProcReplList 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 surroundingTEXTools download package, (installed beneath
double-quotes are part of the parameter as farthe "Sample Scripts" folder).
as Windows is concerned. As far as we'rePermission is granted to freely post or distribute
concerned however, they're not and so we mustthis article so long as it is unedited and credit and
get rid of them. Again, this is a simple mattercopyright information is left intact.
using TEXTools:echo %2| tcl "ReplStr '#22' '' |