0

I'm trying to replace some text in a .yml file using batch.

My code:

@echo off
if not defined in_subprocess (cmd /k set in_subprocess=y ^& %0 %*) & exit )
setlocal enableextensions 

set jruby="%~dp0jruby\bin\jruby"
set someDir="%~dp0..\test\test2"

cd %someDir%
copy /y file.yml test_file.yml > NUL
for /f "tokens=2*" %%i in (file.yml) do @set "password=%%i"
echo Your password --- %password% --- will now be encrypted due to security reasons...

%jruby% -S run_file.rb 

for /f "delims=" %%x in (some_file.rb) do set some_key=%%x

FOR /F "tokens=* USEBACKQ" %%F IN (`%jruby% -S encrypt_property_for_yaml encrypt %some_key% %password%`) DO (
SET encrypted_pw=%%F
)
echo Random 32-Bit encryption key created: %some_key%
echo Password was encrypted to: %encrypted_pw%
echo.
echo Encrypted password will be saved in file.yml file...

set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace%!
    endlocal
)
pause

The error occurs due to this code block

set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace%!
    endlocal
)
pause

The whole thing works perfectly, but as soon as I reach the last FOR-BLOCK where the actual replace takes place, I always get the following error:

! was unexpected at this time

At first I thought it was due to the missing closing bracket on echo, but that still causes the same error.

*Side note: the method I use to find and replace was originally from here

The funny thing is, when I run the same code in a completely separate .bat file, it works flawlessly, but when I use it with the current batch file including other code, I always get the same error. I tried using set instead of >>"%databaseFile%" echo(!line:%search%=%replace%!

I tried googling, found some similar situations where it has something to do with the delayedexpansion but I can't seem to get the FIND and REPLACE to work.

10
  • Show my an example of an "encrypted password" as defined in your examples. Commented Dec 3, 2021 at 10:41
  • @Gerhard something like this: ENC(qQU35msnA699PH9RX18XYQ==) and i checked with echo off, it gets assigned to variable properly Commented Dec 3, 2021 at 10:43
  • 1
    There's you problem. You need to escape the closing parenthesis as ^) The code block is seeing it as a closing parenthesis for itself. Commented Dec 3, 2021 at 10:44
  • @Gerhard you mean the closing parenthesis on the ENC(qQU35msnA699PH9RX18XYQ==) ? I assign it at SET encrypted_pw=%%F, do i add the ^) after the %%F? Commented Dec 3, 2021 at 10:46
  • 1
    ok, so directly before set "replace=%encrypted_pw%" do set "encrypted_pw=%encrypted_pw:)=^)%" I must also warn you, should your password contain ! it will remove it due to delayedexpansion so do consider that as well. There are ways around that though. Commented Dec 3, 2021 at 11:30

1 Answer 1

1

The passwords contains closing parathesis which is seen as a closure of the code block. You need to escape the occurrence of each )

In the below code snipped, I added the replacement section:

set "encrypted_pw=%encrypted_pw:)=^)%"
set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace%!
    endlocal
)
pause

Alterantively, and even better you can make it even shorter and let it be part of the replacement itself in the loop:

set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace:)=^)%!
    endlocal
)
pause

EDIT: to retain open lines.

@echo off
set "search=word to search"
set "replace=to replace"
set "databaseFile=file.yml"

for /f "delims=" %%i in ('type "%databaseFile%" ^| find /n /v "^"  ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    set "line=!line:*]=!"
    >>"%databaseFile%" echo(!line:%search%=%replace%!
    endlocal
)
pause
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.