DragonGamer
DragonGamer

Reputation: 900

Loop through file - long line skipped

The following loop/function is supposed to edit a file (just replacing the second line in the file). The original file contains one > 165000 signs long line and just this line is simply disappearing in the new file after performing this loop.

setlocal EnableDelayedExpansion
set /a count=0
>"%~3" (
  for /f "usebackq delims=" %%A in ("%~2") do  (
    if !count!==1 (echo ^<html^>) else (
      setlocal DisableDelayedExpansion
      echo.%%A
      endlocal)
    set /a count+=1
  )
)
endlocal
goto:eof

I assume that it has to do with the maximum length a variable (%%A) can store.. is there a way to avoid this behavior?

Thanks in advance!

Upvotes: 1

Views: 73

Answers (2)

dbenham
dbenham

Reputation: 130839

Native batch cannot work with lines longer than ~8191 bytes unless you resort to extreme measures that read one byte at a time (it involves creating a dummy file with length >= source, and using FC to derive the bytes). This is one of many reasons why I rarely use batch to modify files.

I would use my JREPL.BAT utility:

call jrepl "^.*" "<html>" /jbegln "skip=(ln!=2)" /f "%~2" /o "%~3" 

But there are many other options.

You could write custom code using JScript or VBS, executed via CSCRIPT. Or you could use PowerShell.

Or you could get a Windows port of sed, or awk, or ...


Update - Possible pure batch solution

The following may work if all of the following are true:

  • You don't care if tabs are converted into a string of spaces
  • The first line length is <= 1021 bytes, and it does not have trailing control characters
  • The total number of lines is <64k
  • (there may be another limitation that I cannot remember)
@echo off
setlocal enableDelayedExpansion
>"%~3" (
  set "ln="
  <"%~2" set /p "ln="
  echo(!ln!
  echo ^<html^>
  more +2 "%~2"
)

Upvotes: 2

Aacini
Aacini

Reputation: 67216

If the first and second lines in the file are less than 1 KB size, then the pure Batch file below should solve your problem:

@echo off
setlocal EnableDelayedExpansion

< "%~2" (

   rem Read the first line from redirected Stdin and copy it to Stdout
   set /P "line="
   echo !line!

   rem Read the second line and replace it by another one
   set /P "line="
   echo ^<html^>

   rem Copy the rest of lines to Stdout
   findstr "^"

) > "%~3"

For further description of this method, see this post; you may also see another example at this one.

Upvotes: 1

Related Questions