Perhaps more complicated than it needs to be, but I wanted to avoid delayed expansion clobbering exclamation marks in your file contents while preserving blank lines. Batch isn't the best language for this sort of thing. If I were you, I'd just use PowerShell or JScript and substring(0, data.length - 1)
or similar.
Anyway, here is a pure batch solution:
@echo off
setlocal
set "file=test.txt"
set "idx=0"
for /f "delims=" %%I in ('findstr /n "^" "%file%"') do (
set /a idx += 1
setlocal enabledelayedexpansion
for %%x in (!idx!) do endlocal & set "line[%%x]=%%I"
)
setlocal enabledelayedexpansion
for %%I in ("!line[%idx%]!") do endlocal & set "lastline=%%~I"
set "line[%idx%]=%lastline:~0,-1%"
setlocal enabledelayedexpansion
>"%file%" (
for /L %%I in (1,1,%idx%) do echo(!line[%%I]:*:=!
)
Here's a batch snippet that abuses PowerShell to accomplish the same task.
>out.txt powershell "$c = (gc test.txt) -join \"`n\"; $c.substring(0, $c.length - 1)"
move /y out.txt test.txt >NUL
Or here's a hybrid batch + JScript solution. Save it with a .bat extension.
@if (@CodeSection == @Batch) @then
@echo off & setlocal
>out.txt (
cscript /nologo /e:Jscript "%~f0" < test.txt
)
move /y out.txt test.txt >NUL
goto :EOF
@end // end batch / begin JScript hybrid chimera
var data = WSH.StdIn.ReadAll();
WSH.StdOut.Write(data.substring(0, data.length - 1));