Перебирайте текстовые файлы, чтобы найти пакет строк - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу найти во всех файлах .config строку «Hello», и, если она найдена, я хочу вызвать функцию findString. Если нет, я хочу продолжить поиск файлов .config.

Это то, что у меня есть, и я не вижу, в чем проблема.

@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"

1 Ответ

0 голосов
/ 15 ноября 2018

Рекурсивный поиск во всех не скрытых * .config файлах строки и ее замена другой строкой - задача, легко достижимая при использовании JREPL.BAT , написанного Дейв Бенхам который представляет собой гибрид пакетного файла / JScript для запуска замены регулярного выражения в файле с помощью 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

Основная причина использования

for /F "eol=| delims=" %%I in ('dir *.config /A-D-H /B /S 2^>nul') do (

из

for /R %%I in (*.config) do (

является тот факт, что последний работает неправильно на дисках с файловой системой FAT32 или ExFAT , если один каталог содержит более одного файла * .config.На дисках с файловой системой NTFS может использоваться также более короткая и немного более быстрая командная строка с использованием только FOR .

В следующем решении используется FINDSTR рекурсивно искать * .config файлы, содержащие буквально и без учета регистра строку Hello, чтобы заменить ее на 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

Конечно, это решение не сообщает о не скрытых * .configфайлы, не содержащие искомой строки, поскольку эти файлы уже отфильтрованы с помощью FINDSTR .

Эти два пакетных файла работают даже в Windows XP и Windows Server 2003.

Другие решениябез использования JREPL.BAT и с использованием только очень ограниченных возможностей командного процессора Windows для обработки строк можно предложить только при знании

  • кодировки символов файлы * .config и
  • , в которых содержатся эти файлы * .config, и
  • , какую строку нужно искать, и
  • , что является строкой замены.

cmd.exe не предназначен для редактирования текстовых файлов.Он предназначен для запуска команд и приложений.Многие другие языки сценариев и, соответственно, их интерпретаторы имеют очень простые в использовании встроенные функции для замены строк в одном или нескольких файлах буквально или с использованием регулярных выражений, таких как JScript, PowerShell, Python, Perl, ...

См.например Измените строку в файле .properties с помощью пакета или Regex в пакетной Windows насколько это сложно и сколько вариантов можно написать для простой строки, замените ее, используя только команды FOR и SET , которые cmd.exe предлагает для работы со строками.Опрашивающие, по крайней мере, опубликовали, что содержит файл для обработки и что они ожидают от пакетного файла, хотя оба опрашивающих также не опубликовали полный список требований.

Для понимания используемых команд и их работы,откройте окно командной строки, выполните там следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • call /? ... объясняет также %~dp0 (диск и путь кокончание пакетного файла всегда расширяется обратной косой чертой) и %~nx0 (только имя файла и расширение пакетного файла), поскольку аргумент 0 всегда является пакетным файлом.
  • cls /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • if /?
  • jrepl.bat /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

Более эффективная помощь по командам Windows может бытьнаходится по адресу:

...