Announcement

Collapse
No announcement yet.

I need to replace content in a .txt file with a batch...Think I'm almost there!

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • I need to replace content in a .txt file with a batch...Think I'm almost there!

    Hi all,

    I have written a batch file to replace some text in a .txt file, but I can't work out why it won't work! The script is as follows:
    ....Moderator Edit: added #tags around the code.
    Code:
    @echo off
     
    setlocal enabledelayedexpansion
     
    FOR /F "usebackq delims=" %%G IN (original.txt) DO (
    Set Line=%%G
    Set Line=!Line:"='!
    Call:replace "!Line!"
    )
     
    goto:eof ------------
    :replace subroutine
    (Set Line=%*&Set Line=!Line:~1,-1!)
    Set Line=!Line:'="!
    Set "Line=!Line: <JobComponents/>
    <CompAttributes/>=<JobComponents>
    <Component>
    <CompComponentCode>VWARM</CompComponentCode>
    <CompSubLocCode>AS</CompSubLocCode>
    ***Blah blah blah*** 
    </Attributes>
    </CompAttributes>!"
    echo.!Line! >>"new file.txt"
    Can anyone work out what's wrong?

    Thanks in advance,

    Mrt2005
    Last edited by Rems; 29th April 2009, 17:00.

  • #2
    Re: I need to replace content in a .txt file with a batch...Think I'm almost there!

    You can give this a try:

    Code:
    @echo off
    setlocal enabledelayedexpansion
    
    Set "FindString=<JobComponents/><CompAttributes/>"
    Set "ReplaceWith=<JobComponents><Component><CompComponentCode>VWARM</CompComponentCode><CompSubLocCode>AS</CompSubLocCode>***Blah blah blah***</Attributes></CompAttributes>"
    
    For /f "delims=" %%a in ( 
       'find.exe /n /v ""^<"c:\original.txt"'
       ) Do (
       (set Line="''%%a")
       (Set Line=!Line:^<=^^^<!) & (Set Line=!Line:^>=^^^>!)
       call:replace
       (echo\!Line!)>>"c:\new file2.txt"
    )
    
    :: end
    
    goto:eof ------------
    :replace  subroutine
    Set/a i = %i% + 1
    (Set Line=!Line:''[%i%]=!)
    Set "FindString2="
    Set "FindString2=%FindString:<=^^^<%"
    Set "FindString2=%FindString2:>=^^^>%"
    Set "ReplaceWith2="
    Set "ReplaceWith2=%ReplaceWith:<=^^^<%"
    Set "ReplaceWith2=%ReplaceWith2:>=^^^>%"
    (Set Line=!Line:%FindString2%=%ReplaceWith2%!)
    (Set Line=%Line:~1,-1%)
    goto:eof ------------
    The point is that special signs to the batch (like "<" and ">") should being escaped (with a caret sign "^") when the sign must be used literaly in a string.
    Furthermore, in cases that the string is pickedup and modified again in the batch before the string is finally echoed then also the added caret signs should be escaped.

    Note, It could be possible that the file "c:\original.txt" does contain also other special signs (?).


    \Rems



    ...-=EDIT=- - - - - - -

    ...[Here is the same code - except that now the outputfile will be new (text will not append) every time you re-run the batch
    Code:
    @echo off
    setlocal enabledelayedexpansion
    
    Set "FindString=<JobComponents/><CompAttributes/>"
    Set "ReplaceWith=<JobComponents><Component><CompComponentCode>VWARM</CompComponentCode><CompSubLocCode>AS</CompSubLocCode>***Blah blah blah***</Attributes></CompAttributes>"
    
    >"c:\new file3.txt" (
       For /f "delims=" %%a in ( 
          'find.exe /n /v ""^<"c:\original.txt"'
          ) Do (
          (set Line="''%%a")
          (Set Line=!Line:^<=^^^<!) & (Set Line=!Line:^>=^^^>!)
          call:replace
          (echo\!Line!)
       )
    )
    
    :: end
    
    goto:eof ------------
    :replace  subroutine
    Set/a i = %i% + 1
    (Set Line=!Line:''[%i%]=!)
    Set "FindString2="
    Set "FindString2=%FindString:<=^^^<%"
    Set "FindString2=%FindString2:>=^^^>%"
    Set "ReplaceWith2="
    Set "ReplaceWith2=%ReplaceWith:<=^^^<%"
    Set "ReplaceWith2=%ReplaceWith2:>=^^^>%"
    (Set Line=!Line:%FindString2%=%ReplaceWith2%!)
    (Set Line=%Line:~1,-1%)
    goto:eof ------------
    Last edited by Rems; 29th April 2009, 22:34.

    This posting is provided "AS IS" with no warranties, and confers no rights.

    __________________

    ** Remember to give credit where credit's due **
    and leave Reputation Points for meaningful posts

    Comment


    • #3
      Re: I need to replace content in a .txt file with a batch...Think I'm almost there!

      if you want to do string manipulation, its better to do it using dedicated tools, like sed/awk (for windows) or using programming languages, like Perl/Python which makes it easy for this task. You can do it with vbscript also
      Code:
      strFile = "c:\test\original.txt"
      Set objFile = objFS.OpenTextFile(strFile)
      Do Until objFile.AtEndOfStream
          strLine = objFile.ReadLine
          If InStr(strLine,"<JobComponents/><CompAttributes/>") > 0 Then
              strLine = "<JobComponents>"& vbCrLf & "<Component>" & vbCrLf & _
              "<CompComponentCode>VWARM</CompComponentCode>" & vbCrLf & _
              "<CompSubLocCode>AS</CompSubLocCode>" & vbCrLf & _
              "***Blah blah blah***" & vbCrLf & "</Attributes>" & vbCrLf & "</CompAttributes>"
          End If 
          WScript.Echo strLine    
      Loop
      output:
      Code:
      C:\test>more original.txt
      line 1
      line 2
      <JobComponents/><CompAttributes/>
      line 4
      line 5
      
      C:\test>cscript /nologo test.vbs  
      line 1
      line 2
      <JobComponents>
      <Component>
      <CompComponentCode>VWARM</CompComponentCode>
      <CompSubLocCode>AS</CompSubLocCode>
      ***Blah blah blah***
      </Attributes>
      </CompAttributes>
      line 4
      line 5
      another way using Perl (if you have it)
      Code:
      $string = <<EOF;
      <JobComponents>
      <Component>
      <CompComponentCode>VWARM</CompComponentCode>
      <CompSubLocCode>AS</CompSubLocCode>
      ***Blah blah blah***
      </Attributes>
      </CompAttributes>!"
      EOF
      
      while (my $line = <>){
        if ($line =~ /<JobComponents\/><CompAttributes\/>/) {
            print $string; next;
        }
        print $line;
      }
      output
      Code:
      C:\test>perl test.pl originaltxt
      line 1
      line 2
      <JobComponents>
      <Component>
      <CompComponentCode>VWARM</CompComponentCode>
      <CompSubLocCode>AS</CompSubLocCode>
      ***Blah blah blah***
      </Attributes>
      </CompAttributes>!"
      line 4
      line 5
      Last edited by ghostdog74; 30th April 2009, 04:06.

      Comment


      • #4
        Re: I need to replace content in a .txt file with a batch...Think I'm almost there!

        Hi Rems,

        I tried your code as below, and unfortunately it doesn't look like I'll be able to do this using just a batch file.
        If I remove ALL spaces and tabs so that what I want to find and replace is one long string, then the script works. However, there will be lots of these files with spaces etc and so will not be feasible to remove manually.


        Code:
         
        @echo off
        setlocal enabledelayedexpansion
        Set "FindString=
            <JobComponents/>
            <CompAttributes/>
          "
        Set "ReplaceWith=<MOBGDETAIL>
                <JobComponents>
              <Component>
                <CompComponentCode>VWARM</CompComponentCode>
                <CompSubLocCode>AS</CompSubLocCode>
                <CompCycleCode>GSER</CompCycleCode>
                <BarCode/>
                <Condition>AGS</Condition>
                <FailureEffect>NA</FailureEffect>
                <Quantity>1</Quantity>
                <FaultNotes/>
                <RectificationNotes/>
                <WarningNotice>No</WarningNotice>
                <WarningNoticeNo/>
                <WarningUnsafeDefect/>
                <WarningUnsafeDefectDesc/>
                <WarningUnsafePosition/>
                <WarningUnsafePositionDesc/>
                <WarningUnsafeFixing/>
                <WarningUnsafeFixingDesc/>
                <GasCappedOffQ1>No</GasCappedOffQ1>
                <GasCappedOffQ2>No</GasCappedOffQ2>
                <CompletionDate>08/12/08 12:21</CompletionDate>
                <ComponentStatus>U</ComponentStatus>
              </Component>
            </JobComponents>
            <CompAttributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS02</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode>45</SubAttribCode>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS10</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS13</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS14</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS15</AttribCode>
                <DateValue/>
                <LogicalValue>Y</LogicalValue>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS16</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS17</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS18</AttribCode>
                <DateValue/>
                <LogicalValue>Y</LogicalValue>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS19</AttribCode>
                <DateValue/>
                <LogicalValue>Y</LogicalValue>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GS27</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode>CP12</SubAttribCode>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>GSO1</AttribCode>
                <DateValue>11/07/06 00:00:00</DateValue>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty>0</AttribQty>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>Make</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty/>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
              <Attributes>
                <AttComponentCode>VWARM</AttComponentCode>
                <AttribCode>Mode</AttribCode>
                <DateValue/>
                <LogicalValue/>
                <SubAttribCode/>
                <AttribQty/>
                <AttsubLocCode>AS</AttsubLocCode>
                <AttCycleCode>GSER</AttCycleCode>
                <AttBarCode/>
              </Attributes>
            </CompAttributes>"
        >"C:\Documents and Settings\curetont\Desktop\Morgans IBS scripts\new file3.txt" (
           For /f "delims=" %%a in ( 
              'find.exe /n /v ""^<"C:\Documents and Settings\curetont\Desktop\Morgans IBS scripts\original.txt"'
              ) Do (
              (set Line="''%%a")
              (Set Line=!Line:^<=^^^<!) & (Set Line=!Line:^>=^^^>!)
              call:replace
              (echo\!Line!)
           )
        )
        :: end
        goto:eof ------------
        :replace  subroutine
        Set/a i = %i% + 1
        (Set Line=!Line:''[%i%]=!)
        Set "FindString2="
        Set "FindString2=%FindString:<=^^^<%"
        Set "FindString2=%FindString2:>=^^^>%"
        Set "ReplaceWith2="
        Set "ReplaceWith2=%ReplaceWith:<=^^^<%"
        Set "ReplaceWith2=%ReplaceWith2:>=^^^>%"
        (Set Line=!Line:%FindString2%=%ReplaceWith2%!)
        (Set Line=%Line:~1,-1%)
        goto:eof ------------
        Sorry to paste the entire code in, it was just in case there is something in there stopping it from working.

        If there is anything obvious, please let me know, otherwise, thanks very much for your time guys!

        Mrt2005

        Comment


        • #5
          Re: I need to replace content in a .txt file with a batch...Think I'm almost there!

          With a batch it is not possible to define a string that is containing linebreaks - your "ReplaceWith" string contains multiple lines and these lines will raise and error and terminate the batch.

          Same with your "FindString". For this string also note that the For-Do statement allows you to parse text line-by-line, since your "FindString" contains multiple lines this could impossible ever be a match anyway.

          You'll have to use a smarter scripting language like ghostdog74 stated. Use Regular Expressions to define a pattern to match with your string.

          Here a vbscript (*vbs file) sample you can give a try:
          Code:
          
          The character count limit is 10000. If I try to paste
          the code here then my post would have contained
          more than 10000 characters.
          The "ReplaceWith" string is rather big so I had to 
          attach the vbs code in a txt file.
          
          
          see attachment

          \Rems
          Attached Files
          Last edited by Rems; 8th May 2009, 21:46.

          This posting is provided "AS IS" with no warranties, and confers no rights.

          __________________

          ** Remember to give credit where credit's due **
          and leave Reputation Points for meaningful posts

          Comment


          • #6
            Re: I need to replace content in a .txt file with a batch...Think I'm almost there!

            Thanks for your time on this! I'll give it a try next week.

            Have good weekend everyone...3 days in the UK!

            Mrt2005

            Comment


            • #7
              Re: I need to replace content in a .txt file with a batch...Think I'm almost there!

              This might be a different way of doing it.. but it works.
              If you know the file name and their corresponding file paths you can easily make changes to hundreds (thousands, whatever) of files at a time. It involves three files.

              The first file I will call sr.cmd
              Code:
              @echo off
              for /f %%i IN (%1) DO call srgo.cmd %%i
              The %1 section is simply a filename that you give it on the command line. We'll call it file.txt Inside file.txt will be the listing of all the files you want to manipulate.

              Code:
              C:\inputfile.txt
              S:\docs\inputfile.txt
              R:\sample1.txt
              sample2.txt
              sample3.txt
              sample4.txt
              sample5.txt
              sample6.txt
              The script will look for file names without paths in the working directory first and probably the path statement.

              It calls a file called srgo.cmd

              Code:
              @echo off
              
              cscript sr.vbs %1  "TEST COMPLETE" "TEST Done"
              
              :end
              The first quoted string "TEST COMPLETE" is what you're looking for. The second quoted string "TEST Done" is what you're replacing it with.

              The script sr.vbs does all the work.
              Code:
              Const ForReading = 1
              Const ForWriting = 2
              
              strFileName = Wscript.Arguments(0)
              strOldText = Wscript.Arguments(1)
              strNewText = Wscript.Arguments(2)
              
              'Do Until strFileName <> ""
              '    strFileName = InputBox("Enter the file name to use.  Enter FULL path e.g. C:\temp\test.txt  " & (Chr(13)) & (Chr(13)) & _
              '    "Type quit to exit", "File Name")
              '    If strFileName = "quit" Then WScript.Quit
                  
              'Loop
              
              
              'Do Until strOldText <> ""
              '    strOldText = InputBox("Enter the string we need to search for.  " & (Chr(13)) & (Chr(13)) & _
              '    "Type quit to exit", "Search String")
              '    If strOldText = "quit" Then WScript.Quit
                  
              'Loop
              
              
              'Do Until strNewText <> ""
              '    strNewText = InputBox("Enter the string that will replace the search string.  " & (Chr(13)) & (Chr(13)) & _
              '    "Type quit to exit", "String Replacement")
              '    If strNewText = "quit" Then WScript.Quit
                  
              'Loop
              
              
              Set objFSO = CreateObject("Scripting.FileSystemObject")
              Set objFile = objFSO.OpenTextFile(strFileName, ForReading)
              
              strText = objFile.ReadAll
              objFile.Close
              strNewText = Replace(strText, strOldText, strNewText)
              
              Set objFile = objFSO.OpenTextFile(strFileName, ForWriting)
              objFile.WriteLine strNewText
              objFile.Close
              
              
              WScript.Echo "Operation completed successfully."
              
              rgo.cmd %%i
              The script with some modification was originally set up to be run from the VB script dialog boxes itself, but with the .cmd files added it will do everything automatically once you set the search/replace parameters and then tell it which file to look in with %1

              Maybe it's complicated but it can do a lot if there are a lot of files to be replaced within.

              So, an example would be this:
              Code:
              C:\scripts>sr.cmd file.txt  <return>
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              Microsoft (R) Windows Script Host Version 5.6
              Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
              
              Operation completed successfully.
              I haven't tested this with .csv, .xls or anything else. It may or may not work with other file extensions.
              Update: You'll need to use VBA for office to do a search and replace. It corrupted my test .xls file.

              Edit: added a compressed folder with all example files needed to run.
              Attached Files
              Last edited by Parkham; 16th May 2009, 17:07. Reason: Added attachment

              Comment

              Working...
              X