Hugo Poirier
Hugo Poirier

Reputation: 3

Batch, use wildcard in set

I want to put a batch file to modify a line in a file in a GPO.

The problem I have is the path is different for each user.

So, I tried to use a wildcard in my path but it doesnt work.

This bat is working:

@echo off &setlocal
setlocal enabledelayedexpansion

set "search=test"
set "replace=test2"
set "textfile=%appdata%\Thunderbird\Profiles\5xu9scdm.default\prefs.js"
set "newfile=%appdata%\Thunderbird\Profiles\5xu9scdm.default\prefs2.js"
(for /f "delims=" %%i in (%textfile%) do (
  set "line=%%i"
  set "line=!line:%search%=%replace%!"
  echo(!line!
))>"%newfile%"
del %textfile%
rename %newfile% prefs.js
endlocal

But if I use a wildcard in the set, it doesnt work anymore.

@echo off &setlocal
setlocal enabledelayedexpansion

set "search=test"
set "replace=test2"
set "textfile=%appdata%\Thunderbird\Profiles\*.default\prefs.js"
set "newfile=%appdata%\Thunderbird\Profiles\*.default\prefs2.js"
(for /f "delims=" %%i in (%textfile%) do (
  set "line=%%i"
  set "line=!line:%search%=%replace%!"
  echo(!line!
))>"%newfile%"
del %textfile%
rename %newfile% prefs.js
endlocal

How can I fix this ?

Upvotes: 0

Views: 480

Answers (1)

aschipfl
aschipfl

Reputation: 34909

You approach does not work, because wild-cards can only occur in the last element of a path. In addition, for /F is not capable of handling wild-cards. So you need to wrap around a for /D loop to resolve the wild-cards, like this (supposing there is only a single matching directory *.default):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "search=test"
set "replace=test2"
set "rootdir=%appdata%\Thunderbird\Profiles\*.default"
set "textfile=prefs.js"
set "newfile=prefs2.js"

for /D %%j in ("%rootdir%") do (
    > "%%~j\%newfile%" (
        for /F "usebackq delims=" %%i in ("%%~j\%textfile%") do (
            set "line=%%i"
            setlocal EnableDelayedExpansion
            set "line=!line:%search%=%replace%!"
            echo(!line!
            endlocal
        )
    )
    > nul move /Y "%%~j\%newfile%" "%%~j\%textfile%"
)

endlocal
exit /B

What I changed besides inserting the for /D loop:

  • delayed expansion is toggled within the loop, so exclamation marks in the text files are not lost;
  • all paths are properly quoted; to use a quoted file path in for /F, usebackq is required;
  • the replacement of the original file by the modified one is done by a single move command rather than del plus rename;

Upvotes: 1

Related Questions