批处理文件用预定义文本替换文本文件中的特定行[关闭]

问题描述 投票:0回答:1

我看过类似的问题,但它们似乎对我不起作用,希望简单一些......(对于专家)......

这是我试图作为批处理文件的一部分进行编辑的配置文件...

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <Accenda.ICG.EndPoint.Properties.Settings>
            <setting name="SiteURL" serializeAs="String">
                <value>https://nww.rss.scarboroughryedaleccg.nhs.uk/_vti_bin/Accenda.ICG.EndPoint.WCF</value>
            </setting>
            <setting name="FilePathToDelete" serializeAs="String">
                <value />
            </setting>
            <setting name="WatchPath" serializeAs="String">
                <value />
            </setting>
            <setting name="MonitorFolderChoice" serializeAs="String">
                <value>True</value>
            </setting>
            <setting name="UserName" serializeAs="String">
                <value />
            </setting>
            <setting name="Password" serializeAs="String">
                <value />
            </setting>
            <setting name="AutoLogin" serializeAs="String">
                <value>True</value>
            </setting>
            <setting name="PollingIntervalMinutes" serializeAs="String">
                <value>5</value>
            </setting>
            <setting name="RegistrySettingsImportedToAppConfig" serializeAs="String">
                <value>True</value>
            </setting>
        </Accenda.ICG.EndPoint.Properties.Settings>
    </userSettings>
</configuration>

对于这里的这一行(或2行)...

    <setting name="WatchPath" serializeAs="String">
        <value />

无论是空,还是填充“任何文件夹”的路径

我只希望它包含以下内容:-

        <setting name="WatchPath" serializeAs="String">
            <value>C:\Users\Public\Desktop\RSS Referrals</value>

如果该值包含路径,我可以很好地组合使用 findstr 和 FART.exe,但如果它为空,我就陷入困境,非常感谢;-)

代码片段(如果该行包含路径):-

for /f "tokens=3 delims=>;<" %%a in ('findstr /C:"C:\Users" "C:\Users\%usr%\AppData\Local\Accenda_Limited\Accenda.ICG.EndPoint.exe_Url_m5l4ujc5t22f3qw0q5uz1dwlfcnrdaoh\1.0.0.15\user.config"') do (
fart -i -c "C:\Users\%usr%\AppData\Local\Accenda_Limited\Accenda.ICG.EndPoint.exe_Url_m5l4ujc5t22f3qw0q5uz1dwlfcnrdaoh\1.0.0.15\user.config" "%%a" "C:\Users\Public\Desktop\RSS Referrals"
)

但是,如果是空的,正如前面提到的,我就卡住了 - 谢谢偷看!!!

arrays batch-file replace cmd
1个回答
1
投票

Windows 命令处理器

cmd.exe
处理批处理文件不适用于文件内容修改任务,尤其不适用于 UTF-8 编码的 XML 文件。 Windows 上默认安装了其他脚本解释器,例如解释 Visual Basic 和 JScript 脚本的 Windows Script Host 以及 PowerShell,它们更适合此类任务。

但是,这里有一个用于此任务的批处理文件。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ConfigFile=%LOCALAPPDATA%\Accenda_Limited\Accenda.ICG.EndPoint.exe_Url_m5l4ujc5t22f3qw0q5uz1dwlfcnrdaoh\1.0.0.15\user.config"
if exist "%ConfigFile%" goto ScanForConfig
echo ERROR: File "%ConfigFile%" not found.
exit /B 4

:ScanForConfig
set "LineNumber="
for /F "delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /L /N /C:"<setting name=\"WatchPath\" serializeAs=\"String\">" "%ConfigFile%" 2^>nul') do set /A LineNumber=%%I + 1
if defined LineNumber goto DesktopFolder
echo ERROR: Could not find ^<setting name="WatchPath" serializeAs="String"^>
echo        in file "%ConfigFile%".
exit /B 3

:DesktopFolder
rem Determine the common desktop folder directly from Windows registry.
rem The first FOR loop is usually enough to get the common desktop folder.
set "CommonDesktop="
for /F "skip=1 tokens=1-3*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Common Desktop" 2^>nul') do if /I "%%I %%J" == "Common Desktop" if not "%%~L" == "" if "%%K" == "REG_SZ" (set "CommonDesktop=%%~L") else if "%%K" == "REG_EXPAND_SZ" call set "CommonDesktop=%%~L"
if not defined CommonDesktop for /F "skip=1 tokens=1-3*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Common Desktop" 2^>nul') do if /I "%%I %%J" == "Common Desktop" if not "%%~L" == "" if "%%K" == "REG_SZ" (set "CommonDesktop=%%~L") else if "%%K" == "REG_EXPAND_SZ" call set "CommonDesktop=%%~L"
if not defined CommonDesktop set "CommonDesktop=\"
if "%CommonDesktop:~-1%" == "\" set "CommonDesktop=%CommonDesktop:~0,-1%"
if defined CommonDesktop if exist "%CommonDesktop%\" goto ScanForValue
if defined PUBLIC if exist "%PUBLIC%\Desktop\" set "CommonDesktop=%PUBLIC%\Desktop" & goto ScanForValue
if exist "%SystemDrive%\Users\Public\Desktop\" set "CommonDesktop=%SystemDrive%\Users\Public\Desktop" & goto ScanForValue
if defined ALLUSERSPROFILE if exist "%ALLUSERSPROFILE%\Desktop\" set "CommonDesktop=%ALLUSERSPROFILE%\Desktop" & goto ScanForValue
echo ERROR: Cannot determine the all users desktop folder.
exit /B 2

:ScanForValue
set "NewValue=<value>%CommonDesktop%\RSS Referrals</value>"
for /F "delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /L /N /C:"%NewValue%" "%ConfigFile%" 2^>nul') do if %LineNumber% == %%I goto NoUpdate

rem It is really necessary to update the value in the configuration file.
set "TempFile=%ConfigFile%.tmp"
(for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "%ConfigFile%" 2^>nul') do (
    set "Line=%%I"
    setlocal EnableDelayedExpansion
    for /F "tokens=1,2 delims=:<>/" %%J in ("!Line!") do if not %%J == %LineNumber% (
        echo(!Line:*:=!
    ) else if "%%K" == "value " (
        echo(!NewValue!
    ) else if "%%K" == "value" (
        echo(!NewValue!
    ) else echo(%%K!NewValue!
    endlocal
))>"%TempFile%"
move /Y "%TempFile%" "%ConfigFile%"
if not exist "%TempFile%" goto UpdateDone

del "%TempFile%"
echo ERROR: Failed to modify file "%ConfigFile%".
exit /B 1

:NoUpdate
echo There is nothing to update.
exit /B 0

:UpdateDone
echo Configuration update done successfully.
endlocal

注意:
仅当 XML 文件

user.config
发布时,此批处理文件才有效,并且在
value
的行下方始终有一行带有标记
<setting name="WatchPath" serializeAs="String">
的行。 XML 文件内容结果的任何其他变体都可能在执行批处理文件后导致 XML 文件损坏。

请阅读我的答案如何逐行读取和打印文本文件的内容?以获取有关如何完成行替换的信息。

我建议您还阅读维基百科文章,其中描述了预定义的 Windows 环境变量

我对制作不在当前目录中的目录的回答描述了用于获取桌面文件夹的命令行,在这种情况下,代码被修改为获取所有用户的公共桌面文件夹,而不是用户的桌面文件夹。

如果要修改的值已存在于带有

<setting name="WatchPath" serializeAs="String">
的行下方,则批处理文件不会修改配置文件。

我建议再次为此任务编写 PowerShell 脚本,而不是使用批处理文件,因为这样会更安全、更快。对于因在更改的 XML 文件内容上使用此批处理脚本而导致的 XML 文件损坏,我不承担任何责任。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • del /?
  • echo /?
  • endlocal /?
  • exit /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • move /?
  • rem /?
  • set /?
  • setlocal /?

PS:只要找到要更新的文件,该批处理文件甚至可以在 Windows XP 上运行,而默认情况下

%LOCALAPPDATA%
则不然,因为 Windows XP 上默认没有定义环境变量
LOCALAPPDATA
,只是在Windows Vista 和更新的 Windows 版本。

© www.soinside.com 2019 - 2024. All rights reserved.