пакетный скрипт - найти и заменить строку, которая начинается с определенного значения в INI-файле - PullRequest
0 голосов
/ 09 октября 2018

Здравствуйте, и, во-первых, я хотел бы извиниться за это сообщение, если на него уже отвечали ранее.Я провел последние 4 часа в поисках Stackoverflow и Google.

У меня есть файл gamesettings.ini, который я хотел бы редактировать с помощью командного файла.Мне нужно выполнить это на многих компьютерах, поэтому я хотел бы сохранить в файле другие настройки, кроме двух строк.

Две строки, которые я пытаюсь изменить:

CustomVoiceChatInputDevice = Ввод по умолчанию
CustomVoiceChatOutputDevice = Выход по умолчанию

Я пробовал несколько пакетных сценариев, которые я нашел в Stackoverflow, но они работают, только если я задаю полную строку.Поскольку для каждого пользователя установлены разные параметры, мне нужен сценарий, чтобы просто взять начало строки.Например, «CustomVoiceChatInputDevice».

Вот пример кода, который я использовал, благодаря @jsanchez.Этот скрипт не работает, если я не наберу всю строку:

Спасибо за ваше время !!

@echo off
::Use the path from whence the script was executed as
::the Current Working Directory
set CWD=C:\

::***BEGIN MODIFY BLOCK***
::The variables below should be modified to the
::files to be changed and the strings to find/replace
::Include trailing backslash in _FilePath
set _FilePath=C:\Users\NEOSTORM\AppData\Local\RedDeadGame\Saved\Config\WindowsClient\
set _FileName=GameUserSettings.ini
::_WrkFile is the file on which the script will make
::modifications.
set _WrkFile=GameUserSettings.bak
set OldStr="CustomVoiceChatInputDevice"
set NewStr="CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game)"

::***END MODIFY BLOCK***

::Set a variable which is used by the
::search and replace section to let us
::know if the string to be modified was
::found or not.
set _Found=Not found

SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

if not exist "%_FilePath%%_FileName%" goto :NotFound

::If a backup file exists, delete it
if exist "%_FilePath%%_WrkFile%" (
    echo Deleting "%_FilePath%%_WrkFile%" 
    del "%_FilePath%%_WrkFile%" >nul 2>&1
    )

echo.
echo Backing up "%_FilePath%%_FileName%"...
copy "%_FilePath%%_FileName%" "%_FilePath%%_WrkFile%" /v

::Delete the original file. No worries, we got a backup.
if exist "%_FilePath%%_FileName%" del "%_FilePath%%_FileName%"
echo.
echo Searching for %OldStr% string...
echo.
for /f "usebackq tokens=*" %%a in ("%_FilePath%%_WrkFile%") do (
    set _LineChk=%%a
    if "!_LineChk!"==%OldStr% (
        SET _Found=Found 
        SET NewStr=!NewStr:^"=! 
        echo !NewStr!
        ) else (echo %%a)
        )>>"%_FilePath%%_FileName%" 2>&1

::If we didn't find the string, rename the backup file to the original file name
::Otherwise, delete the _WorkFile as we re-created the original file when the
::string was found and replaced.
if /i "!_Found!"=="Not found" (echo !_Found! && del "%_FilePath%%_FileName%" && ren "%_FilePath%%_WrkFile%" %_FileName%) else (echo !_Found! && del "%_FilePath%%_WrkFile%")
goto :exit

:NotFound
echo.
echo File "%_FilePath%%_FileName%" missing. 
echo Cannot continue...
echo.
:: Pause script for approx. 10 seconds...
PING 127.0.0.1 -n 11 > NUL 2>&1
goto :Exit

:Exit
exit /b

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Каждый параметр в вашем файле .ini идентифицирует название параметра.Таким образом, порядок строк не должен иметь значения , возможно, не имеет значения.

Если порядок строк не имеет смысла, то все, что вам нужно сделать, это использоватьFINDSTR / V, чтобы удалить старые значения, а затем просто добавить новые значения.В приведенном ниже сценарии я изменяю оба значения одновременно.

@echo off
setlocal enableDelayedExpansion

set "iniLoc=C:\Users\NEOSTORM\AppData\Local\RedDeadGame\Saved\Config\WindowsClient"
set "iniFile=%iniLoc%\GameUserSettings.ini"
set "iniBackup=%iniLoc%\GameUserSettings.bak"
set "CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game)"
set "CustomVoiceChatOutputDevice=Some new value"

>"%iniFile%.new" (
  findstr /vb "CustomVoiceChatInputDevice= CustomVoiceChatOutputDevice=" "%iniFile%"
  echo CustomVoiceChatInputDevice=!CustomVoiceChatInputDevice!
  echo CustomVoiceChatOutputDevice=!CustomVoiceChatOutputDevice!
)
copy "%iniFile%" "%iniBackup%"
ren "%iniFile%.new" *.

Было бы немного быстрее создать файл резервной копии с помощью переименования, а не копирования, но затем был бы короткий момент, когда INI-файлне существует.

0 голосов
/ 09 октября 2018

Командный процессор Windows не предназначен для редактирования текстовых файлов, он предназначен для запуска команд и приложений.

Но эту задачу редактирования / замены текстового файла, тем не менее, можно выполнить с помощью cmd.exe (очень медленно):

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FileName=%LOCALAPPDATA%\RedDeadGame\Saved\Config\WindowsClient\GameUserSettings.ini"
set "TempFile=%TEMP%\%~n0.tmp"
if not exist "%FileName%" goto EndBatch

del "%TempFile%" 2>nul

for /F delims^=^ eol^= %%A in ('%SystemRoot%\System32\findstr.exe /N "^" "%FileName%"') do (
    set "Line=%%A"
    setlocal EnableDelayedExpansion
    if not "!Line:CustomVoiceChatInputDevice=!" == "!Line!" (
        echo CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game^)
    ) else if not "!Line:CustomVoiceChatOutputDevice=!" == "!Line!" (
        echo CustomVoiceChatOutputDevice=Line (Astro MixAmp Pro Game^)
    ) else echo(!Line:*:=!
    endlocal
) >>"%TempFile%"

rem Is the temporary file not binary equal the existing INI file, then move
rem the temporary file over existing INI file and delete the temporary file
rem if that fails like on INI file currently opened by an application with
rem no shared write access. Delete the temporary file if it is binary equal
rem the existing INI file because of nothing really changed.

%SystemRoot%\System32\fc.exe /B "%TempFile%" "%FileName%" >nul
if errorlevel 1 (
    move /Y "%TempFile%" "%FileName%"
    if errorlevel 1 del "%TempFile%"
) else del "%TempFile%"

:EndBatch
endlocal

См. Ответ на Как читать и печатать содержимое текстового файла построчно? для объяснения цикла FOR .

Обратите внимание на символ вставки ^ слева до ) в двух строках для вывода.Закрывающая скобка за пределами строки аргумента в двойных кавычках должна быть экранирована с помощью ^, так как в противном случае ) будет интерпретироваться командным процессором Windows как конец блока команд, а не как буквальный символ для вывода командой ECHO ,Другие символы, имеющие особое значение для cmd.exe при разборе командной строки или всего блока команд, например &|<>, также должны быть экранированы с помощью ^ в ECHO командных строках.

Пожалуйста, примитетакже посмотрите статью в Википедии о Переменные среды Windows .Настоятельно рекомендуется использовать правильные предопределенные переменные среды для путей к папкам, таких как папка данных локального приложения.

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

  • call /? ... объясняет %~n0 ... имя пакетного файла без пути и расширения файла.
  • del /?
  • echo /?
  • endlocal /?
  • fc /?
  • findstr /?
  • for /?
  • if /?
  • move /?
  • rem /?
  • set /?
  • setlocal /?
...