1

I got this code (in this question) that finds and replaces string but it adds a blank new line at the end of the output file and makes it not usable.

@echo off &setlocal
set "Russian=g_language = Russian"
set "English=g_language = English"

set "textfile=user.cfg"
set "newfile=user.bak"

Call :SwapLang Russian

:search
Color 9B
@echo off&prompt :&mode con cols=60 lines=16


echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo                      PLEASE RUN NOTEPAD
echo.
echo.
echo.
echo.
echo.

:search
TIMEOUT /T 2
TASKLIST|FIND "notepad.exe"
IF %ERRORLEVEL% equ 0 (GOTO found) ELSE (GOTO search)

:found

Call :SwapLang English

Goto :Eof

:SwapLang %1 byRef
( for /f "delims=" %%i in (%textfile%) do (
  set "line=%%i"
  setlocal EnableDelayedExpansion
  If /I "!line:~0,12!" Equ "g_language =" (
    echo(!%1!
  ) Else (
    echo(!line!
  )
  endlocal
)) > "%newfile%"
del %textfile%
rename %newfile%  %textfile%
Goto :Eof

INPUT FILE: It has 6 line with no blank line.

sys_usefrontline = 1
net_frontline_address = s1.gmru.net
net_frontline_port = 5050
g_language = Russian
cl_promoPageWidth = 820
cl_promoPageHeight = 726

OUTPUT1 FILE: It has 7 lines, last line is blank (can't be shown here).

sys_usefrontline = 1
net_frontline_address = s1.gmru.net
net_frontline_port = 5050
g_language = Russian
cl_promoPageWidth = 820
cl_promoPageHeight = 726

OUTPUT2 FILE: It has 7 lines, last line is blank(can't be shown here).

sys_usefrontline = 1
net_frontline_address = s1.gmru.net
net_frontline_port = 5050
g_language = English
cl_promoPageWidth = 820
cl_promoPageHeight = 726

Could someone help me with this?

Mac Maca
  • 13
  • 5
  • There is nothing in the code to produce an additional line. Do you mean "The last line in my Input File has no termination (`CRLF`)"? Does the `CRLF` really make the file unusable? – Stephan Aug 27 '17 at 17:59
  • I dont know realy. – Mac Maca Aug 27 '17 at 18:39
  • @Stephan Echo always terminates a line with a cr/lf. The very last line of the file didn't and shouldn't have a cr/lf. I went to PowerShell but it's Set-Content did the same. Only way around I found was dot net's `[IO.File]::WriteAllText()` –  Aug 27 '17 at 20:46

2 Answers2

0

Batch isn't ideal for editing files. This batch uses PowerShell to do the editing with a Regular Expression:

:: Q:\Test\2017\08\25\SO_45879928.cmd
@echo off &setlocal

set "textfile=user.cfg"

Call :SwapLang Russian

:search
Color 9B
@echo off&prompt :&mode con cols=60 lines=16
echo.
echo.
echo                      PLEASE RUN NOTEPAD
echo.
echo.
:search
TIMEOUT /T 2
TASKLIST|FIND "notepad.exe"
IF %ERRORLEVEL% equ 0 (GOTO found) ELSE (GOTO search)

:found

Call :SwapLang English

Goto :Eof

:SwapLang %1
Powershell -NoP -C "$txt=(gc %textfile% -raw) -replace '(?<=g_language = )(English|Russian)','%1';[IO.File]::WriteAllText('%textfile%', $txt)"

Goto :Eof
  • Result is same as for batch from above. I think I will give up from this approach and try copy>rename file approach. – Mac Maca Aug 27 '17 at 20:20
  • Looks like `sc` or `Set-Content` also puts a terminating cd/lf to the end of the file [refernce](https://stackoverflow.com/questions/30751320/powershell-replace-content-in-file-adds-redundent-carriage-return) Workaround from the answer in the reference incorporated in my answer here. Should work now. –  Aug 27 '17 at 20:24
  • @ LotPings I have to thank you for your time and effort that you invested in answering my questions! – Mac Maca Aug 27 '17 at 20:56
  • The most welcome thank is: If you find an answer helpful you should consider to [accept the answer](http://stackoverflow.com/help/accepted-answer) and/or [vote up](https://stackoverflow.com/help/why-vote) –  Aug 27 '17 at 20:58
  • Now it deletes file content in first pass @ `Call :SwapLang Russian` – Mac Maca Aug 27 '17 at 20:59
  • I checked with the very last version and found no problem? Do the other values in the file change regularly? What about a simple `copy /y Russian.cfg user.cfg` or `copy /y English.cfg user.cfg`? –  Aug 27 '17 at 21:12
0

I've solved your original question: Batch check and replace string then wait for a process by just 2 command lines using msr.exe as following: (full message is there, with a colorful screenshot)

msr -p user.cfg -it "(g_language\s*=\s*)\w*" -o "${1}Russian" -R

msr -p user.cfg -it "(g_language\s*=\s*)\w*" -o "${1}English" -R

Additonaly, for your questions here, also 1 command to remove tail new lines:

msr -p your-files-dirs -S -t "[\r\n]+$" -o "" -R

Or remove tail white-spaces and new lines:

msr -p your-files-dirs -S -t "\s+$" -o "" -R

According to stackoverflow rules, say again here: msr.exe/msr.gcc*/msr.cygwin etc is in my open project https://github.com/qualiu/msr tools directory, as a general tool to Match/Search/Replace files/pipe lines/blocks.

Community
  • 1
  • 1
Quanmao
  • 92
  • 5