Reputation: 45
I want to search all .config files for a string "Hello" and if it is found I want to call the function findString. If not, I want it to continue searching .config files.
This is what I have and I do not see what the problem is.
@echo off
setlocal EnableExtensions
:TOP
for /R %%f in (*.config) do (
findstr /i "Hello" "%%f" >NUL
if errorlevel 1 (
call :findString
) else (
goto TOP
)
pause
exit /b
)
:findString
set "textfile=%1"
Upvotes: 0
Views: 3227
Reputation: 49216
Searching recursively in all non-hidden *.config files for a string and replacing it with another string is an easy to achieve task on using JREPL.BAT written by Dave Benham which is a batch file / JScript hybrid to run a regular expression replace on a file using JScript.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
cls
if not exist "%~dp0jrepl.bat" (
echo Batch file "%~nx0" requires batch file JREPL.BAT in
echo directory: "%~dp0"
echo/
echo Please download it from:
echo/
echo https://www.dostips.com/forum/viewtopic.php?f=3^&t=6044
echo/
echo Extract the batch file in downloaded ZIP archive file into
echo directory: "%~dp0"
goto EndBatch
)
set "Search=Hello"
set "Replace=Goodbye"
echo Processing *.config files in entire directory tree starting in:
echo "%CD%"
echo/
set "FilesCount=0"
set "FoundCount=0"
for /F "eol=| delims=" %%I in ('dir *.config /A-D-H /B /S 2^>nul') do (
set /A FilesCount+=1
%SystemRoot%\System32\findstr.exe /M /I /L /C:"%Search%" "%%I" >nul
if errorlevel 1 (
echo File "%%I" does not contain "%Search%".
) else (
set /A FoundCount+=1
echo File "%%I" contains "%Search%" replaced by "%Replace%".
rem Replace case-insensitive literally the string "%Search%" by string "%Replace%".
call "%~dp0jrepl.bat" "%Search%" "%Replace%" /I /L /F "%%I" /O -
rem Insert here more command lines to execute on *.config file
rem containing literally the string to find in the file.
)
)
echo/
if %FilesCount% == 1 (set "PluralS=") else set "PluralS=s"
echo Updated %FoundCount% of %FilesCount% *.config file%PluralS%.
:EndBatch
endlocal
echo/
pause
The main reason for using
for /F "eol=| delims=" %%I in ('dir *.config /A-D-H /B /S 2^>nul') do (
instead of
for /R %%I in (*.config) do (
is the fact that the latter does not work correct on drives with FAT32 or ExFAT file system in case of one directory contains more than one *.config file. On drives with NTFS file system the shorter and a bit faster command line using only FOR could be used too.
The next solution uses FINDSTR to search recursively for *.config files containing literally and case-insensitive the string Hello
to replace it by Goodbye
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
cls
if not exist "%~dp0jrepl.bat" (
echo Batch file "%~nx0" requires batch file JREPL.BAT in
echo directory: "%~dp0"
echo/
echo Please download it from:
echo/
echo https://www.dostips.com/forum/viewtopic.php?f=3^&t=6044
echo/
echo Extract the batch file in downloaded ZIP archive file into
echo directory: "%~dp0"
goto EndBatch
)
set "Search=Hello"
set "Replace=Goodbye"
echo Processing *.config files in entire directory tree starting in:
echo "%CD%"
echo/
set "FoundCount=0"
for /F "eol=| delims=" %%I in ('%SystemRoot%\System32\findstr.exe /M /I /L /S /C:"%Search%" "*.config"') do (
set /A FoundCount+=1
echo File "%%I" contains "%Search%" replaced by "%Replace%".
rem Replace case-insensitive literally the string "%Search%" by string "%Replace%".
call "%~dp0jrepl.bat" "%Search%" "%Replace%" /I /L /F "%%I" /O -
rem Insert here more command lines to execute on *.config file
rem containing literally the string to find in the file.
)
echo/
if %FoundCount% == 1 (set "PluralS=") else set "PluralS=s"
echo Updated %FoundCount% *.config file%PluralS%.
:EndBatch
endlocal
echo/
pause
Of course this solution does not report non-hidden *.config files not containing the searched string as those files are already filtered out by FINDSTR.
These two batch files work even on Windows XP and Windows Server 2003.
Other solutions without using JREPL.BAT and with using only very limited capabilities of Windows command processor for string handling can be suggested only on knowing
cmd.exe
is not designed for editing text files. It is designed for running commands and applications. Lots of other scripting languages respectively their interpreters have very easy to use built-in functions to replace strings in one or more files literally or using a regular expression like JScript, PowerShell, Python, Perl, ...
See for example Modify a string in a .properties file with batch or Regex in Batch Windows how difficult it is and how much variants can be written for a simple string replace using only the commands FOR and SET which cmd.exe
offers for working with strings. The questioners have at least posted what the file to process contains and what they expect from the batch file although a complete list of requirements was also not posted by both questioners.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
... explains also %~dp0
(drive and path of batch file ending expanded always with a backslash) and %~nx0
(only file name and extension of batch file) because of argument 0 is always the batch file.cls /?
echo /?
endlocal /?
findstr /?
for /?
if /?
jrepl.bat /?
pause /?
rem /?
set /?
setlocal /?
More and better help on Windows commands can be found at:
Upvotes: 1