Read line per line a txt file with VBS - vbscript

I'm trying this code:
filename = "test.txt"
listFile = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
For Each line In listLines
WScript.Echo line
'My Stuff
Next
Or this other:
filename = "test.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(filename, ForReading)
Do Until f.AtEndOfStream
myLine = f.ReadLine
WScript.Echo myLine
'My Stuff
Loop
Why in both cases it echoes all lines at once, and of course I'm unable to work line by line? Any idea?

Your file has funny EndOfLine markers. Let's assume the lines are terminated by vbLf:
>> fn = "lf.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbLf)
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>> WScript.Echo ts.ReadLine
>> loop
>>
a
b
c
As you can see, .ReadLine can cope with vbLf (unix). Your Split() on .ReadAll(), however, will fail:
>> t = goFS.OpenTextFile(fn).ReadAll()
>> a = Split(t, vbCrLf)
>> WScript.Echo UBound(a)
>> WScript.Echo a(0)
>>
0
a
b
c
t does not contain a single vbCrLf, so Split() returns an array with UBound() == 0, containing t as its single element. .Echoing that will at least look like 3 (4) lines. You could Split() on vbLf, if you really need an array of lines.
But if your files contains vbLf endings, then the .ReadLine loop should work fine.
.ReadLine() can't cope with vbCr (mac):
>> fn = "cr.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbCr)
>>
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>> WScript.Echo ts.ReadLine
>> loop
>>
c
The b+cr 'overwrites' the a+cr and is then 'overwritten' by c+cr. The .ReadAll() approach will fail too, unless you use vbCr as separator.
But if your files contains vbCr endings, then none of your snippets can "echoe(s) all lines at once".
Does your file come from outer space?
Update wrt comment:
You can't read UTF-8 using the Filesystemobject. Either convert the file to UTF-16 and use the Unicode option of the format parameter when .OpenTextFile it, or work with an ADODB Stream.
It still would be interesting to know what EOL marker is used.

Your code seems to be working fine. I changed it slightly to show that the lines are, in fact, read line-by-line:
Set fso=CreateObject("Scripting.FileSystemObject")
filename = "test.txt"
listFile = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
i = 0
For Each line In listLines
WScript.Echo CStr(i) + " : " + line
i = i + 1
'My Stuff
Next
I assume fso is set in your script somewhere, but I added that extra line just for completeness.
You should verify that your input file does, indeed, have multiple lines separated by vbCrLf. The counter i helps in debugging each line as it shows the line index during reading the lines.

Related

How to create a new file by searching specific text in old file

My OLDFile looks like FolderList.txt with the content:
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20140825_123400
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20140827_065126
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20141006_094447
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20141006_110546
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20141008_105947
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20150917_093710
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20151005_190254
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20151005_191124
And I want to create a new file with name FolderListNew.txt and the content:
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20141006_110546
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20141008_105947
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20150917_093710
\\srv10177\temppahir$\Desktop\WORK\6758\Archive\Article\20151005_190254
So basically I want to do a search on 2 text:
Text1 = 20141006_110546
Text2 = 20151005_190254
and pull the lines from the first occurrence of Text1 until Text2 occurs.
Assume data will always be something like this and will be in sorted format ascending as per these timestamp.
I have tried the below script, which doesn't work and is incomplete:
Option Explicit
Dim objFSO, msg, Filename, file, filestreamOUT, objFile, strContents, strLine, line, Text1, Text2, OLDFilename, tmpStr, MyPos
Set objFSO = CreateObject("Scripting.FileSystemObject")
Text1 = "20141006_110546"
Text2 = "20151005_190254"
OLDFilename="C:\Users\IBM_ADMIN\Desktop\VB\Folderlist.txt"
WScript.Echo "String to find is : " & Text1
Wscript.Echo "OLDFilename is " & OLDFilename
Set objFile = objFSO.OpenTextFile(OLDFilename, 1)
Wscript.Echo "Reading file the first time:"
strContents = objFile.ReadAll
Wscript.Echo "Line being read is" & strContents
WScript.Echo "tmpStr.ReadLine is : " & Line
'MyPos = InStr (tmpStr.ReadLine, Text1)
WScript.Echo "MyPos value is : " & MyPos
If MyPos >= 0 Then
'WScript.Echo "Match NOT Found in File and tmpStr.ReadLine is : " & tmpStr.ReadLine
Else
WScript.Echo "string value is : " & strLine
WScript.Echo "Match Found in File and tmpStr.ReadLine is : " & tmpStr.ReadLine
End If
If you want to put specific lines from one file into another file it's best to read the source file line by line:
Set inFile = objFSO.OpenTextFile(OLDFilename)
Do Untile inFile.AtEndOfStream
line = inFile.ReadLine
...
Loop
inFile.Close
Start writing the output file if the line contains Text1 and stop writing after it contained Text2:
Text1 = "20141006_110546"
Text2 = "20151005_190254"
writeOutput = False
Set inFile = objFSO.OpenTextFile("C:\path\to\input.txt")
Set outFile = objFSO.OpenTextFile("C:\path\to\output.txt", 2, True)
Do Until inFile.AtEndOfStream
line = inFile.ReadLine
If InStr(line, "20141006_110546") > 0 Then writeOutput = True
If writeOutput Then outFile.WriteLine line
If InStr(line, "20151005_190254") > 0 Then Exit Do
Loop
inFile.Close
outFile.Close

Vbs script read txt file with file names then search if taht file exist and move another file

I found this code:
Option Explicit ' .. Just coz.
Const forReading = 1 ' Set our constants for later.
Const forWriting = 2 ' ....
Dim inputFile, outputFile, fso, fileList, logFile, fileSpec ' Dimension our variables
inputFile = "filelist.txt" ' Our input file
outputFile = "missing.txt" ' Our output file
Set fso = CreateObject("Scripting.FileSystemObject") ' Set up fso
Set fileList = fso.OpenTextFile(inputFile, forReading) ' Open our input file for reading
If Not (fso.FileExists(outputFile)) Then fso.CreateTextFile(outputfile) ' Create output file if it doesn't exist
Set logFile = fso.OpenTextFile(outputFile, forWriting) ' Open up our output file for writing later
Do while not fileList.AtEndOfStream ' While we have lines to process do this loop
fileSpec = fileList.ReadLine() ' Read in line of text as variable fileSpec
If Not (fso.FileExists(fileSpec)) Then ' If it doesnt exist ....
logFile.writeline (fileSpec) ' ....Write it out to the output file
End If
Loop
fileList.close ' Clean up
logFile.close
Here is explanation of that code.
I need one more thing. I need move extra files from default directory (they are not write in filelist.txt) into the new directory. I need in default directory only files who are write in filelist.txt. I don't fully understand that code. I was try remake that code but each time failed.
Set problems (union, difference, ...) can be solved with a Dictionary in VBScript.
You have two sets of file names, one from your source file (SetF), one from the files in your default directory (SetD). In your existing loop over SetF, store the the names in a dictionary (DicF). Then add a loop over SetD (DefFolder.Files) and move the files that don't exist in DicF - as in:
>> SetF = Split("A D F G")
>> SetD = Split("B D G H")
>> Set DicF = CreateObject("Scripting.Dictionary")
>> For Each f in SetF
>> DicF(f) = 0
>> Next
>> For Each f In SetD
>> If Not DicF.Exists(f) Then
>> WScript.Echo f
>> End If
>> Next
>>
B
H
(cf. Compare arrays)

VBScript To Remove Number from filename

I'm looking for a VBscript which scan a folder for files and remove number from filenames. for example if we have a file named "target1990.txt" then It should be "target.txt"
Can anyone help please?
Use a RegExp that looks repeatedly/globally for a sequence of digits (\d+) and replace all matches with "" (nix):
>> set r = New RegExp
>> r.Global = True
>> r.Pattern = "\d+"
>> s = "target1990.txt"
>> WScript.Echo s, r.Replace(s, "")
>>
target1990.txt target.txt
further sample (same regexp):
>> s = "t1ar33get19s90.txt"
>> WScript.Echo s, r.Replace(s, "")
>>
t1ar33get19s90.txt targets.txt

VBScript Carriage Returns

I write the following VB script in order to run commands from WIN XP on Linux machine and redirect the output command to out.txt file ( under C:\ )
My VB script I print the /etc/hosts file from Linux machine in to out.txt file
Script works fine but I have one problem:
/etc/hosts file was printed in out.txt file with one long line , in place of three lines
Example: (out.txt)
127.0.0.1 localhost 19.20.183.99 MY_IP 10.10.10.10 LOOP
In place to print the following host file in out.txt
127.0.0.1 localhost
19.20.183.99 MY_IP
10.10.10.10 LOOP
MY VB script
Const TARGET_HOST = "19.20.183.99"
const PATH = "cat /etc/hosts"
const LOGIN = "root"
const PASS = " dgdgd "
Const PLINKPATH="""C:\dir1\plink.exe"""
Set Sh = CreateObject("WScript.Shell")
CMD = " echo y | " & PLINKPATH & " -ssh -pw " & PASS & LOGIN & "#" & TARGET_HOST & " " & PATH
Sh.Run "cmd /k" & CMD & " > ""C:\out.txt""" , 1, True
Please advice what I need to fix in my VB script in order to print the correct hosts file ( line by line ) and not as one long line ?
Try to do a replace of lf (line feed) for lf and cr (carriage return). Linux only has LFs, where windows also requires the carriage return to show the extra line.
Alternatively, open the file in Notepad++ and you'll notice that the lines are printed line by line. (http://notepad-plus-plus.org/download/v6.4.5.html)
EDIT:
Try the following after you outputted the file to replace the line feeds (reference: link):
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\out.txt", ForReading)
strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, chr(10), chr(13) & chr(10))
Set objFile = objFSO.OpenTextFile("C:\out.txt", ForWriting)
objFile.WriteLine strNewText
objFile.Close

VBScript cut off end of filename after space but keep extension

I've been searching online. Is there a way to cut off the space and the rest of the filename but leave the extension with VBScript.
Say I have a filename like this:
filename this is a file.txt
Could VBScript cut off the space and everything afterwards but leave the extension like this:
filename.txt
Sure, you can do some surgery with the string functions available in vbscript.
dim s
dim s2
s = "filename this is a file.txt"
s2 = Left(s, Instr(s, " ")-1) & Right(s, Len(s) - InstrRev(s, ".") + 1)
msgbox s2
There are several ways to achieve what you want:
Using a regular expression:
Set fso = CreateObject("Scripting.FileSystemObject")
Set re = New RegExp
re.Pattern = "^(\S*).*(\..*?)$"
Set f = fso.GetFile("filename this is a file.txt")
f.Name = re.Replace(f.Name, "$1$2")
Using Split:
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile("filename this is a file.txt")
f.Name = Split(fso.GetBaseName(f))(0) & "." & fso.GetExtensionName(f)
Using string functions: see answer provided by KekuSemau.
Use a RegExp to cut the first 'word' and the extension from your input:
>> Set r = New RegExp
>> r.Pattern = "^(\w+)(.*)(\..*)$"
>> For Each s In Array("filename this is a file.txt", "a.txt", "1a nix ...txt")
>> WScript.Echo s, """" & r.Replace(s, "$1$3") & """"
>> Next
>>
filename this is a file.txt "filename.txt"
a.txt "a.txt"
1a nix ...txt "1a.txt"
If you insist on staying with String ops, use Mid() instead of Right():
>> s = "filename this is a file.txt"
>> a = Left(s, InStr(s, " ") - 1)
>> b = Mid(s, InStrRev(s, "."))
>> WScript.Echo a, b, a & b
>>
filename .txt filename.txt

Resources