Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: This is Bug in .bat file?  (Read 11476 times)

0 Members and 1 Guest are viewing this topic.

Star-Fire

    Topic Starter


    Rookie
    This is Bug in .bat file?
    « on: October 16, 2009, 10:33:15 AM »
     I'm bad English and newbie DOS

     I have .bat file:

    Quote
    for %%a in ("*.txt") do type %%a >> outfile.out
    @echo off
    setlocal  enabledelayedexpansion
    for /f "tokens=*" %%a in (outfile.out) do (
     set line=%%a
     echo !line:~0,30!>> Final.out
     )

     This file have 2 problem:
     -It will read all file txt but can't read file .txt have space in file name (by DOS?)
     -when echo line, it will loss all character flow exclamation symbol (!)
     Example:
     
      .txt file:
     
    Quote
    this is a song!in love                     ABC

      Final.out:
     
    Quote
    this is a song love           

     .out file loss 3 character "!in"

     Can you fix they help me, plz :P
    I'm bad English

    wbrost



      Intermediate
    • Thanked: 11
      Re: This is Bug in .bat file?
      « Reply #1 on: October 16, 2009, 01:49:47 PM »
      I have .bat file:

      Code: [Select]
      for %%a in ("*.txt") do type %%a >> outfile.out
      @echo off
      setlocal  enabledelayedexpansion
      for /f "tokens=*" %%a in (outfile.out) do (
       set line=%%a
       echo !line:~0,30!>> Final.out
       )


      1)Try changing the .out to .txt
      2)set the delims equal to something that is not in the file like the following:
      delims==
      3)change the ECHO line to !line! only

      Code: [Select]
      @ECHO OFF
      SETLOCAL ENABLEDELAYEDEXPANSION
      for %%a in ("*.txt") do type %%a >> outfile.txt
      for /f "delims== tokens=*" %%a in (outfile.txt) do (
       set line=%%a
       echo !line!>> Final.txt
       )

      let me know if you have any issues or questions.

      Salmon Trout

      • Guest
      Re: This is Bug in .bat file?
      « Reply #2 on: October 16, 2009, 05:05:16 PM »
      Quote
      change the ECHO line to !line! only

      How will he get the first 30 characters only of the line?

      Salmon Trout

      • Guest
      Re: This is Bug in .bat file?
      « Reply #3 on: October 17, 2009, 02:25:00 AM »
      Batch language uses certain special characters for control purposes. E.g. !&<> and others. Text files containing these are difficult to process. Exclamation mark is such a character. Therefore other scripting language is useful. Frequently Visual Basic Script either alone or in hybrid script is a solution. If running Scripting Host is allowed and enabled, this will work.

      Enclose filenames (or variables which will expand to a filename) with quotes to include names with spaces.

      This script is closest to the original....

      Code: [Select]
      @echo off
      set script="%TEMP%\stringslice.vbs"
      echo wscript.echo mid(wscript.arguments(0), (wscript.arguments(1)+1),wscript.arguments(2))>%script%
      for %%a in ("*.txt") do type "%%a" >> outfile.out
      for /f "tokens=*" %%b in (outfile.out) do (
       for /f "delims==" %%c in ( 'cscript //nologo %script% "%%b" 0 30' ) do echo %%c>>final.out
       )
      del %script%

      Note that outfile.out and final.out with grow each time you run the script.

      In fact the processing of outfile.out can be done in one line but the above is clearer to read I think

      Code: [Select]
      @echo off
      set script="%TEMP%\stringslice.vbs"
      echo wscript.echo mid(wscript.arguments(0), (wscript.arguments(1)+1),wscript.arguments(2))>%script%
      for %%a in ("*.txt") do type "%%a" >> outfile.out
      for /f "tokens=*" %%b in (outfile.out) do for /f "delims==" %%c in ( 'cscript //nologo %script% "%%b" 0 30' ) do echo %%c>>final.out
      del %script%

      You can eliminate outfile.out altogether by taking the 2nd token of the output of findstr /R "." ("." is regular expression to match all characters). [You could use type *.txt but it produces screen echo of each filename.]

      Code: [Select]
      @echo off
      set script="%TEMP%\stringslice.vbs"
      echo wscript.echo mid(wscript.arguments(0), (wscript.arguments(1)+1),wscript.arguments(2))>%script%

      for /f "tokens=1,2 delims=:" %%a in ('findstr /R "." *.txt') do (
      for /f "delims==" %%c in ( 'cscript //nologo %script% "%%b" 0 30') do (
      echo %%c>>final.out
      )
      )
      del %script%

      In fact you can do all the processing on one line but it is 153 characters long.

      Code: [Select]
      @echo off
      set script="%TEMP%\stringslice.vbs"
      echo wscript.echo mid(wscript.arguments(0), (wscript.arguments(1)+1),wscript.arguments(2))>%script%

      for /f "tokens=1,2 delims=:" %%a in ('findstr /R "." *.txt') do for /f "delims==" %%c in ( 'cscript //nologo %script% "%%b" 0 30') do echo %%c>>final.out

      del %script%

      « Last Edit: October 17, 2009, 10:51:38 AM by Salmon Trout »

      Salmon Trout

      • Guest
      Re: This is Bug in .bat file?
      « Reply #4 on: October 17, 2009, 04:33:13 AM »
      Code: [Select]
      wscript.echo mid(wscript.arguments(0), (wscript.arguments(1)+1),wscript.arguments(2))
      alternative:
      save the above code as stringslice.vbs either in the same folder as the batch file, or in a folder on your PATH*, and you can use it in any batch file and the batch file posted by the OP becomes a one liner

      Code: [Select]
      for /f "tokens=1,2 delims=:" %%a in ('findstr /R "." *.txt') do for /f "delims==" %%c in ( 'cscript //nologo %script% "%%b" 0 30') do echo %%c>>final.out
      Use it like this

      offset and length are numbers (same as batch string slicing)

      Code: [Select]
      set longstring=This is a long string
      for /f "delims==" %%a in ( 'cscript //nologo stringslice.vbs "%longstring%" offset length' ) do set substring=%%a


      * or you can supply the full path to the vbs script
      « Last Edit: October 17, 2009, 11:56:52 AM by Salmon Trout »

      Star-Fire

        Topic Starter


        Rookie
        Re: This is Bug in .bat file?
        « Reply #5 on: October 17, 2009, 09:31:14 AM »
         @Salmon Trout:
         I tested all your code and it worked but have new problem. Its very slow, I can't use it with many file text have hight size (200,000+ Byte with 3000 line) in short time like old my .bat. :'(

        I'm bad English

        gh0std0g74



          Apprentice

          Thanked: 37
          Re: This is Bug in .bat file?
          « Reply #6 on: October 17, 2009, 09:53:23 AM »
          its very slow because the batch has 3 for loops.... The first loop iterates a text file with 3000 lines and save to an output file. then the second loop does that 3000 times and the next loop as well...furthermore,  with many text files...you do your own maths....

          a more efficient approach is to read those text files 1 time only, and get your desired substring from index 0 to 30
          ie
          Code: [Select]
          for ( loop *.txt ) do (
              echo substr(line,0,30)
          )

          you can use this vbscript
          Code: [Select]
          Set objFS=CreateObject("Scripting.FileSystemObject")
          strFolder = "c:\test"
          Set objFolder = objFS.GetFolder(strFolder)
          Go (objFolder)
          Sub Go(objDIR)
            If objDIR <> "\System Volume Information" Then
              For Each eFolder in objDIR.SubFolders
                Go eFolder
              Next   
            End If
          For Each strFile In objDIR.Files
          name =strFile.Name
          If objFS.GetExtensionName(strFile) = "txt" Then
          Set objFile = objFS.OpenTextFile(name)
          Do Until objFile.AtEndOfStream
          strLine = objFile.ReadLine
          WScript.Echo Mid(strLine,1,30)
          Loop
              Set objFile = Nothing         
          End If
          Next
          End Sub
          save as myscript.vbs and on command line:
          Code: [Select]
          c:\test> cscript /nologo myscript.vbs

          best of all, if you can download stuff...try gawk..(see my sig) for parsing files.
          Code: [Select]
          C:\test>gawk "{print substr($0,1,30)}" *.txt

          Salmon Trout

          • Guest
          Re: This is Bug in .bat file?
          « Reply #7 on: October 17, 2009, 10:20:50 AM »
          its very slow because the batch has 3 for loops.... The first loop iterates a text file with 3000 lines and save to an output file. then the second loop does that 3000 times and the next loop as well...furthermore,  with many text files...you do your own maths....

          I don't think all my suggested solutions do that, actually.

          Quote from: gh0std0g74
          a more efficient approach is to read those text files 1 time only

          Didn't you notice my further examples which specifically avoid temp files? I actually mentioned this explicitly.

          But I agree batch is slow. Also calling the vbs repeatedly has a big effect.

          Code: [Select]
          @echo off

          set script="%TEMP%\stringslice.vbs"
          echo wscript.echo mid(wscript.arguments(0), (wscript.arguments(1)+1),wscript.arguments(2))>%script%

          REM For each line output by findstr /R "." *.txt, in the format filename:line
          REM put the part after the colon into %%b
          REM (This is equivalent to running type on every .txt file in the folder)
          REM This is gh0std0g74's "one time only" file read.
          for /f "tokens=1,2 delims=:" %%a in ('findstr /R "." *.txt') do (

               REM Put the first 30 characters into %%c
          for /f "delims==" %%c in ( 'cscript //nologo %script% "%%b" 0 30') do (

          REM Append these as a new line to a file
          echo %%c>>final.out

          )

          )
          « Last Edit: October 17, 2009, 11:54:02 AM by Salmon Trout »

          Helpmeh



            Guru

          • Roar.
          • Thanked: 123
            • Yes
            • Yes
          • Computer: Specs
          • Experience: Familiar
          • OS: Windows 8
          Re: This is Bug in .bat file?
          « Reply #8 on: October 17, 2009, 10:23:24 AM »

          And you needed to repeat that post even though it was the most recent post?
          Where's MagicSpeed?
          Quote from: 'matt'
          He's playing a game called IRL. Great graphics, *censored* gameplay.

          Salmon Trout

          • Guest
          Re: This is Bug in .bat file?
          « Reply #9 on: October 17, 2009, 10:25:28 AM »
          And you needed to repeat that post even though it was the most recent post?

          huh?

          Salmon Trout

          • Guest
          Re: This is Bug in .bat file?
          « Reply #10 on: October 17, 2009, 11:14:42 AM »

          Geek-9pm


            Mastermind
          • Geek After Dark
          • Thanked: 1026
            • Gekk9pm bnlog
          • Certifications: List
          • Computer: Specs
          • Experience: Expert
          • OS: Windows 10
          Re: This is Bug in .bat file?
          « Reply #11 on: October 17, 2009, 11:43:19 AM »
          Quote
          Quote
          this is a song!in love                     ABC

            Final.out:
           
          Quote
          this is a song love           

           .out file loss 3 character "!in"

          That is not a a bug. In standard English we would not put an "!" inside of a word.
          That symbol us an escape for the command interpreter.
          The output is correct. Nothing is wrong. But it is not what you wanted.
          the variable "in" was not defined, so you get nothing. A null string.

          gh0std0g74



            Apprentice

            Thanked: 37
            Re: This is Bug in .bat file?
            « Reply #12 on: October 17, 2009, 05:42:40 PM »
            I don't think all my suggested solutions do that, actually.
            ...
            Didn't you notice my further examples which specifically avoid temp files? I actually mentioned this explicitly.
            OP mentioned he has used all your solution and its slow and he has big files. therefore my hypothesis is that he had used the one that has used the version with the most number of redundant loops...and you can be sure i read your post.


            Quote
            Code: [Select]
            ....
            for /f "tokens=1,2 delims=:" %%a in ('findstr /R "." *.txt') do (
                 REM Put the first 30 characters into %%c
            for /f "delims==" %%c in ( 'cscript //nologo %script% "%%b" 0 30') do (
            ....
            though its an improved version, there's still no reason to invoke cscript 3000 * n  times for each lines of each text file. its better to do them in one invocation of cscript process (since considering they are big files)

            Salmon Trout

            • Guest
            Re: This is Bug in .bat file?
            « Reply #13 on: October 18, 2009, 02:27:49 AM »
            Quote
            there's still no reason to invoke cscript 3000 * n  times for each lines of each text file

            Cscript is invoked ***once*** for each line of each text file.
            « Last Edit: October 18, 2009, 02:46:57 AM by Salmon Trout »

            Salmon Trout

            • Guest
            Re: This is Bug in .bat file?
            « Reply #14 on: October 18, 2009, 02:56:41 AM »
            I wonder, gh0std0g74, if you have tested your vbs solution?