0

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"
JoeHio
  • 35
  • 5
  • Why not simply use `findstr /IMS "Hello" *.config` –  Nov 15 '18 at 15:59
  • You are confused on the logic. You do not need the `ELSE` clause or the `GOTO` or the `EXIT` inside the `FOR` command. You do need an `EXIT` after the closing parentheses of the `FOR` command. – Squashman Nov 15 '18 at 16:01
  • You are also confused on the `ERRORLEVEL`. If the string is found the `ERRORLEVEL` will be 0. So you actually need to do `IF NOT ERRORLEVEL 1`. Which means if errorlevel is not greater than or equal to one. – Squashman Nov 15 '18 at 16:16

1 Answers1

1

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

  • character encoding of the *.config files and
  • which lines those *.config files really contain and
  • what is the string to search for and
  • what is the replace string.

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:

Mofi
  • 38,783
  • 14
  • 62
  • 115