I have a situation where I’d like to add text to the end each line in a text file on a windows system. It’s not an option to have the files on a UNIX system where it would probably be easier and faster.
Actually I would ideally like to do this to a whole bunch of text files.
i.e.
Enright3 line one
blah blah line two
here is a string of numbers 123412341234
should be…
Enright3 line oneTextAddedHere
blah blah line twoTextAddedHere
here is a string of numbers 123412341234TextAddedHere
In your opinion what would be faster than using a dos batch file to accomplish this?
In my mind I’d use the DOS For command; something like:
for /f “delims=” %%a in (c:\filename.txt) Do (echo %@aTextAddedHere >> newFile.txt)
Suggestions? Ideas?
The above syntax may not be 100% correct but I’m pretty sure it’s close. I haven’t used DOS commands in a while. Basically remembering to turn echo off so I don’t see the crap it’s writing to a file.
The easiest way is to use a scripting language. I’m most familiar with Perl, which I know does have a Windows port, although I haven’t used it in a while so I don’t remember if there are any tricks to getting it working.
If you go that way, here’s a simple Perl script that will do what you want. (Note that it doesn’t have any logic to skip blank lines, so if you have those and don’t want text put there, let me know and I’ll show you how to put an if-statement to ignore them.)
#! /usr/bin/perl
if ($#ARGV < 0) {
print "syntax: endline [filename(s)]
";
exit;
}
$newendl = "TextAddedHere";
foreach $file (@ARGV[0..$#ARGV]) {
open (IN,"$file") or die "Can't open $file: $!
";
$outfile = join '',$file,'.newendl';
open (OUT,">$outfile");
LINE: while ($line=<IN>) {
chomp $line;
print OUT "$line$newendl
";
}
close IN;
close OUT;
}
Thanks Giraffe, I’ll have to try this out with some speed tests on large files. I don’t care much about difficulty (since I’ll write it as one size fits all, and then not touch it again) as I do about overall speed. Blank lines aren’t a problem either as if there are blank lines there’s something wrong with the source file.
Ah, I misunderstood your OP – I thought you meant the fastest way to get something in place, not the fastest from a performance standpoint.
For raw I/O speed, I’m guessing you’ll get the best performance writing something in C or C++ and playing with the stream buffer sizes. I’ve heard that C streams are a bit faster than C++, but I’ve never cared enough about I/O performance enough to worry about it. I’m guessing both will do a fair amount better than Perl.
For this purpose, VBScript has a few advantages. For one, it won’t choke on ampersands and other special characters like a batch script will. For another, you don’t have to install anything extra; it’s built into all modern versions of Windows.
To try it out, paste the script below into a text file with a .vbs extension. Customize the value of the strFolder variable on line 1 with the location of the folder containing the text files. Customize the value of the strNewText variable on line 3 with the text to append to each line. Customize the value of the strOutputFolder variable on line 4 with the location of the folder to write the new files to.
Running the script, e.g. with cscript scriptname.vbs, will create new text files in the output folder with the specified text appended to each line.
strFolder = "C: ext files"
strExt = "txt"
strNewText = "TextAddedHere"
strOutputFolder = "C:\output"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strFolder)
If Not objFSO.FolderExists(strOutputFolder) Then
objFSO.CreateFolder strOutputFolder
End If
For Each objFile In objFolder.Files
strFile = objFile.Path
strFileExt = objFSO.GetExtensionName(strFile)
If LCase(strFileExt) = strExt Then
arrText = TextFileToArray(strFile)
strNewFile = strOutputFolder & "\" & objFile.Name
Set objNewFile = objFSO.CreateTextFile(strNewFile, True)
For Each strLine In arrText
objNewFile.WriteLine strLine & strNewText
Next
objNewFile.Close
End If
Next
Function TextFileToArray(strTextFile)
Const ForReading = 1
Const TriStateUseDefault = -2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile( _
strTextFile, ForReading, False, TriStateUseDefault)
strTextContents = objTextFile.ReadAll
objTextFile.Close
TextFileToArray = Split(strTextContents, vbCrLf)
End Function