Problem with BatchSubstitute.bat

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
rafaelbc
Posts: 2
Joined: 17 Dec 2009 04:45

Problem with BatchSubstitute.bat

#1 Post by rafaelbc » 18 Dec 2009 05:55

Hello,

I found BatchSubstitute.bat really useful, but then I started having problems when the file contained information like the example below:
hey, "this is a example & test file", ain't it?

If the file contains a line with a '&' between double quotes, I get errors like:
'test' is not recognized as an internal or external command, operable program or batch file.
'hey' is not recognized as an internal or external command, operable program or batch file.

Any hints on how I could have that problems fixed?

Thanks in advance!

avery_larry
Expert
Posts: 391
Joined: 19 Mar 2009 08:47
Location: Iowa

#2 Post by avery_larry » 18 Dec 2009 15:53

Well, since the "&" symbol is a special character, one obvious (and frankly preferred) solution is to mofidy the code and replace "&" with "and" wherever appropriate.

If you must use the & symbol, you can try to escape it with a ^


hey, "this is a example ^& test file", ain't it?

However, from the error output you show, I'm expecting that you need that line to be either ECHO or REM:

rem hey, "this is a example & test file", ain't it?

rafaelbc
Posts: 2
Joined: 17 Dec 2009 04:45

#3 Post by rafaelbc » 21 Dec 2009 04:44

BatchSubstitute.bat is one of the batch files provided by DosTips, so that is the error that is output to me when I run it - I have no special needs for ECHOing or REMing.

When I enter:
$ BatchSubstitute.bat a b test.txt

Where test.txt contains that string, I get those errors.

I appreciate the answer, however I have no chance for manually replacing '&' for 'and' or '^&', since the files I'm working with are provided by someone else (the string I used was merely an example).

Any ideas about what I could do?

DosItHelp
Expert
Posts: 239
Joined: 18 Feb 2006 19:54

#4 Post by DosItHelp » 22 Dec 2009 00:38

The batch file described at http://www.dostips.com/DtCodeBatchFiles.php#Batch.FindAndReplace has limitations. If the text file to be searched/replaced contains on of the characters &|<> in a line without being quoted then the batch will not process this line correctly. (A proper note has been added to the post.)

The following script acts opposite. It only works if the special characters &|<> are quoted if they appear (rafaelbc this may help in your case):

Code: Select all

@echo off
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL DISABLEDELAYEDEXPANSION

::BatchSubstitude - parses a File line by line and replaces a substring"
::syntax: BatchSubstitude.bat OldStr NewStr File
::          OldStr [in] - string to be replaced
::          NewStr [in] - string to replace with
::          File   [in] - file to be parsed
if "%*"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1* delims=]" %%A in ('type %3^|find /n /v ""') do (
    set "line=%%B"
    if defined line (
        call echo.%%line:%~1=%~2%%
    ) else (echo.)
)

Output:
C:\>type BatchSubstitute.txt
!!! THIS TEST DOESN`T REPLACE ANYTHING, IT JUST CHECKS MAKES SURE
!!! THE SCRIPT WORKS FOR SPECIAL CHARACTERS
!!! THE SCRIPT DOESN'T WORK CORRECTLY IF ANY OF THE CHARACTERs "&|^"
!!! APPEAR IN A LINE WITHOUT BEING QUOTED.
Next line is empty

this ( is a opening bracket character
this ) is a closing bracket character
this % is a percent character
this ! is an exclamation character
this " is a quote character
this > is a grater-than character
this < is a less-than character
this & is an ampersand character
this | is a vertical character
this ^ is a up character

this is a "quoted string"
this is a %percented string%
this is a !exclamationed string!
a "quoted ( opening bracket"
a "quoted ) closing bracket"
a "quoted % quote character"
a "quoted ! quote character"
a "quoted " quote character"
a "quoted > grater-than bracket"
a "quoted < less-than bracket"
a "quoted & ampersand"
a "quoted | vertical"
a "quoted ^ up character"

C:\>BatchSubstitute2.bat Oldtext Newtext BatchSubstitute.txt
!!! THIS TEST DOESN`T REPLACE ANYTHING, IT JUST CHECKS MAKES SURE
!!! THE SCRIPT WORKS FOR SPECIAL CHARACTERS
!!! THE SCRIPT DOESN'T WORK CORRECTLY IF ANY OF THE CHARACTERs "&|^"
!!! APPEAR IN A LINE WITHOUT BEING QUOTED.
Next line is empty

this ( is a opening bracket character
this ) is a closing bracket character
this % is a percent character
this ! is an exclamation character
this " is a quote character
this a grater-than character
this a less-than character
this is a up character

this is a "quoted string"
this is a %percented string%
this is a !exclamationed string!
a "quoted ( opening bracket"
a "quoted ) closing bracket"
a "quoted % quote character"
a "quoted ! quote character"
a "quoted " quote character"
a "quoted > grater-than bracket"
a "quoted < less-than bracket"
a "quoted & ampersand"
a "quoted | vertical"
a "quoted ^ up character"

If however you have a mixed case, where sometimes the special character &|<> appear within quotes and not within quotes, then there seems to be no clean batch file solution for a search and replace.

ghostmachine4
Posts: 319
Joined: 12 May 2006 01:13

Re: Problem with BatchSubstitute.bat

#5 Post by ghostmachine4 » 22 Dec 2009 02:55

rafaelbc wrote:Any hints on how I could have that problems fixed?

do yourself a favour and use something better than batch for parsing/replacing text. you can use vbscript if you are the native guy, or you can use good string parsing/replacement tools like sed/gawk. here's an example with vbscript

Code: Select all

Set objFS=CreateObject("Scripting.FileSystemObject")
strOld = WScript.Arguments.Item(0)
strNew = WScript.Arguments.Item(1)
strFile = WScript.Arguments.Item(2)
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
   strLine = objFile.ReadLine
   WScript.Echo Replace(strLine,strOld,strNew)
Loop


Save the above as replace.vbs and on the command line

Code: Select all


C:\test>type file
this is a line with ampersand &
the && "" text i want " to change is this word called "test"
this is the end line with quotes " " " "

C:\test>cscript //nologo test.vbs test newword file
this is a line with ampersand &
the && "" text i want " to change is this word called "newword"
this is the end line with quotes " " " "


No worries about & or " messing up.
you can save to another file using the redirection > operator.

DosItHelp
Expert
Posts: 239
Joined: 18 Feb 2006 19:54

#6 Post by DosItHelp » 22 Dec 2009 23:28

Good point ghostmachine4.
To make it transparent to batch users here a batch function that creates the vb script on the fly and uses it.

Code: Select all

@echo off
::BatchSubstitude - parses a File line by line and replaces a substring"
::syntax: BatchSubstitude.bat OldStr NewStr File
::          OldStr [in] - string to be replaced
::          NewStr [in] - string to replace with
::          File   [in] - file to be parsed
if "%*"=="" findstr "^::" "%~f0"&GOTO:EOF
call:replaceInFile %*
goto:eof


::--------------------------------------------------------
::-- Function section starts below here
::--------------------------------------------------------


:replaceInFile oldText newText file -- replaces a string in a text file
::                                  -- OldStr [in] - string to be replaced
::                                  -- NewStr [in] - string to replace with
::                                  -- File   [in] - file to be parsed:$created 20091222 :$changed 20091222 :$categories FileOperation,VB
:$source http://www.dostips.com
Setlocal Disabledelayedexpansion
set "fn=%0"
set "fn=%fn:~1%.vbs"
md "%temp%.\dostips.com\" >NUL 2>&1
REM the xcopy helps checking if the vbs file needs to be created or re-created
xcopy /diyl "%~f0?" "%temp%.\dostips.com\%fn%"|find "1 File(s)">NUL&&(
    set "cpy="
    (for /f "tokens=1* delims=]" %%A in ('find /v /n "" "%~f0"') do (
        if "%%B"=="'%fn%" set "cpy=Y"
        if "%%B"=="EXIT /b" set "cpy="
        if defined cpy call echo.%%B
    ))>"%temp%.\dostips.com\%fn%"
    REM echo.Updated:"%temp%.\dostips.com\%fn%"
)
cscript //nologo "%temp%.\dostips.com\%fn%" %*
exit /b
'replaceInFile.vbs
'$created 20091222 '$changed 20091222
'$source http://www.dostips.com
'$creatorbatch %~f0,%date%,%time%
Set objFS=CreateObject("Scripting.FileSystemObject")
strOld = WScript.Arguments.Item(0)
strNew = WScript.Arguments.Item(1)
strFile = WScript.Arguments.Item(2)
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
   strLine = objFile.ReadLine
   WScript.Echo Replace(strLine,strOld,strNew)
Loop
EXIT /b

ghostmachine4
Posts: 319
Joined: 12 May 2006 01:13

#7 Post by ghostmachine4 » 23 Dec 2009 00:23

i think hybrids should be avoided as far as possible. I recommend just using vbscript, since vbscript can do most of the thing batch does and code is cleaner and easier to read and debug.

drocks
Posts: 3
Joined: 29 Dec 2010 06:30

Re: Problem with BatchSubstitute.bat

#8 Post by drocks » 29 Dec 2010 06:40

I also found the BatchSubstitute.bat really useful - Thank you.

Is there a way it can be modified to except regular expressions, such as /.*$ (to get all from a / to the end of the line)? I have tried modifying BatchSubstitute.bat for findstr /R, but I break it each time I touch it (i'm sort of new at this). If Dos batch is not correct, a vbs would do as well -

Amy help would be much appreciated!!

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Problem with BatchSubstitute.bat

#9 Post by aGerman » 29 Dec 2010 08:45

Yeah I think VBScript is a better way to handle regex patterns, but vbs is kinda off topic in this forum. How ever, have a look at the msdn. It shows how to do.

Regards
aGerman

ghostmachine4
Posts: 319
Joined: 12 May 2006 01:13

Re: Problem with BatchSubstitute.bat

#10 Post by ghostmachine4 » 29 Dec 2010 09:40

drocks wrote:I also found the BatchSubstitute.bat really useful - Thank you.

Is there a way it can be modified to except regular expressions, such as /.*$ (to get all from a / to the end of the line)? I have tried modifying BatchSubstitute.bat for findstr /R, but I break it each time I touch it (i'm sort of new at this). If Dos batch is not correct, a vbs would do as well -

Amy help would be much appreciated!!


again, if you want a native solution, vbscript or powershell is the way to go. Otherwise, if you can use tools, download GNU sed or gawk for windows, which are good at parsing and doing things to text/strings, especially using regex.

drocks
Posts: 3
Joined: 29 Dec 2010 06:30

Re: Problem with BatchSubstitute.bat

#11 Post by drocks » 29 Dec 2010 13:21

Thank you very much for this. It looks like vbs is the way to go. With the help of the sight you mentioned I found an example of a vb script which almost does exactly what I need (pasted below - you will probably recognize it, except that I pasted in /.*$ in the search expression). But I can't quite figure out the syntax to replace the strings which resulted from the search. In other words, I want to replace all the text found with /.*$ with a blank. In the example below, they are replacing the text "PT" with "" (a blank) for any lines which contain /.*$. I need to somehow replace the expression "PT" to be that of the results of the search. Any thoughts on where I could find the correct expressions to do that?


Const ForReading = 1
Const ForWriting = 2

Set fso = CreateObject("Scripting.FileSystemObject")
Set objRE = CreateObject("VBScript.RegExp")
objRE.Global = True
objRE.IgnoreCase = False
objRE.Pattern = "/.*$"

Set inFile = fso.OpenTextFile("c:\temp\file.txt", ForReading)
Set outFile = fso.OpenTextFile("c:\temp\file.chg", ForWriting, True)

Do Until inFile.AtEndOfStream
strLine = inFile.ReadLine
Set colMatches = objRE.Execute(strLine)
If colMatches.Count > 0 Then
strLine = Replace(strLine, "PT "")
End If
outFile.WriteLine strLine
Loop

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Problem with BatchSubstitute.bat

#12 Post by aGerman » 29 Dec 2010 15:38

Code: Select all

strLine = Replace(strLine, "PT", "")

Otherwise give an example line and show what you try to do.

Regards
aGerman

drocks
Posts: 3
Joined: 29 Dec 2010 06:30

Re: Problem with BatchSubstitute.bat

#13 Post by drocks » 30 Dec 2010 10:45

Thank you, I appreciate the response. I ended up getting lucky and found exactly what I needed at the site (http://www.computerhope.com/forum/index ... 02.15.html) from user Sidewinder. I did not want to post his work here, better going to the source - but is it a great solution to what I was looking for.

Thanks again!

Post Reply