首先发布在这里。
我正在尝试使用其他文本文件中的字符串将字符串更新(或添加)到纯文本文件。
示例:
File1.txt (参考文件)
<add key="1" value="False" />
<add key="2" value="C:\Temp" />
<add key="3" value="True" />
<add key="4" value="True" />
<add key="5" value="False" />
<add key="6" value="False" />
<add key="7" value="False" />
<add key="8" value="False" />
<add key="9" value="False" />
<add key="10" value="newkey" />
<add key="11" value="False" />
<add key="12" value="127.0.0.1" />
<add key="13" value="True" />
<add key="14" value="True" />
<add key="15" value="False" />
<add key="16" value="False" />
<add key="17" value="False" />
<add key="18" value="True" />
<add key="19" value="True" />
<add key="20" value="True" />
<add key="21" value="True" />
<add key="22" value="True" />
File2.txt (目标文件)
<150 strings>
</150 strings>
<appSettings>
<add key="1" value="False" />
<add key="2" value="False" />
<add key="3" value="False" />
<add key="4" value="False" />
<add key="5" value="False" />
<add key="6" value="False" />
<add key="7" value="False" />
<add key="8" value="False" />
<add key="9" value="False" />
<add key="10" value="False" />
<add key="11" value="False" />
<add key="12" value="False" />
<add key="13" value="False" />
<add key="14" value="False" />
<add key="15" value="False" />
<add key="16" value="False" />
<add key="17" value="False" />
<add key="18" value="False" />
<add key="19" value="False" />
<add key="20" value="False" />
<add key="21" value="False" />
<add key="22" value="False" />
</appSettings>
<startup>
<supportedRuntime/>
</startup>
</configuration>
要求:
如果file2.txt已包含一个或所有密钥(即1到22),我想用file1.txt的密钥替换密钥。
如果file2.txt缺少file1.txt中存在的任何键,则需要添加它们。只要它们出现在<AppSettings>
内,订单就无所谓了。
如果file2.txt包含file1.txt中不存在的键,则应将它们单独保留。
<AppSettings>
以外的任何内容都应保持不变。
在简要测试了Dbenham的最后一个脚本之后,看起来它完成了所有内容,但是上面和下面的行被移动了(我的错误是没有提供完整的示例)。
以下是Dbenham剧本的当前输出:
<150 strings>
</150 strings>
<appSettings>
</appSettings>
<startup>
<supportedRuntime/>
</startup>
</configuration>
<add key="1" value="False" />
<add key="2" value="C:\Temp" />
<add key="3" value="True" />
<add key="4" value="True" />
<add key="5" value="False" />
<add key="6" value="False" />
<add key="7" value="False" />
<add key="8" value="False" />
<add key="9" value="False" />
<add key="10" value="newkey" />
<add key="11" value="False" />
<add key="12" value="127.0.0.1" />
<add key="13" value="True" />
<add key="14" value="True" />
<add key="15" value="False" />
<add key="16" value="False" />
<add key="17" value="False" />
<add key="18" value="True" />
<add key="19" value="True" />
<add key="20" value="True" />
<add key="21" value="True" />
<add key="22" value="True" />
答案 0 :(得分:1)
@ECHO OFF
SETLOCAL
:: remove variables starting $ or #
For %%b IN ($ #) DO FOR /F "delims==" %%a In ('set %%b 2^>Nul') DO SET "%%a="
FOR /f "delims=" %%a IN (reference.txt) DO FOR /f "tokens=3delims== " %%h IN ("%%a") DO (
SET "$%%~h=%%a"
)
FOR /f "delims=" %%a IN (target.txt) DO FOR /f "tokens=3delims== " %%h IN ("%%a") DO (
SET "#%%~h=%%a"
)
(
FOR /F "tokens=1*delims=$=" %%c In ('set $ 2^>Nul') DO (
ECHO(%%d
SET "#%%c="
)
FOR /F "tokens=1*delims==" %%c In ('set # 2^>Nul') DO (
ECHO(%%d
)
)>newfile.txt
GOTO :EOF
您的源数据具有“智能引号” - 我假设您实际使用了引号。
Essentailly,将$keyname
=行设置为引用; #keyname
=来自目标的行
然后输出所有$keyname
并清除具有相同键名的任何#keyname
。
最后,输出所有剩余的#keyname
s
结果显示在newfile.txt
答案 1 :(得分:0)
以下是基于更新问题的新答案
你真的应该使用一种用于编辑XML的工具。有许多方法可以以仍然有效的方式修改配置文件(file2.txt),但这会破坏任何纯批处理解决方案。但是,假设布局没有改变你所显示的......
如果你需要做的就是用file1.txt的内容替换file2.txt中的appSettings,那么:
@echo off
setlocal enableDelayedExpansion
set "replace="
>file2.txt.new (
for /f "delims=" %%A in (file2.txt) do (
set "ln=%%A"
if "!ln:</appSettings>=!" neq "!ln!" (
type file1.txt
set "replace="
)
if not defined replace echo(!ln!
if "!ln:<appSettings>=!" neq "!ln!" set replace=1
)
)
move /y file2.txt.new file2.txt >nul
上面的不保留file2.txt中找不到的任何在file1.txt中不存在的密钥。
如果你需要保存file2.txt中不存在于file1.txt中的密钥,那么修改Magoo的答案可能是最简单的解决方案:
@echo off
setlocal enableDelayedExpansion
for /f "delims==" %%A in ('set $ 2^>nul') do set "%%A="
set "replace="
>file2.txt.new (
for /f "delims=" %%A in (file2.txt) do (
set "ln=%%A"
if not defined replace (
echo(!ln!
if "!ln:<appSettings>=!" neq "!ln!" set replace=1
) else if "!ln:</appSettings>=!" equ "!ln!" (
for /f tokens^=2^ delims^=^" %%K in ("%%A") do set "$%%K=%%A"
) else (
for /f "delims=" %%B in (file1.txt) do for /f tokens^=2^ delims^=^" %%K in ("%%B") do set "$%%K=%%B"
for /f "tokens=1* delims==" %%B in ('set $') do echo(%%C
echo(!ln!
set "replace="
)
)
)
move /y file2.txt.new file2.txt >nul
上述两种解决方案都会破坏包含!
的内容。如果需要支持!
,则可以进行更改。解决方案还假设密钥不区分大小写。
此外,两个解决方案都将从file2.txt中删除空行。但这与XML文档无关。可以添加一些额外的代码来保留空行。
<强> 更新 强>
以下是第二个解决方案的修改版本,该内容在内容中保留!
个字符:
@echo off
setlocal disableDelayedExpansion
for /f "delims==" %%A in ('set $ 2^>nul') do set "%%A="
set "replace="
set "endReplace="
>file2.txt.new (
for /f "delims=" %%A in (file2.txt) do (
set "ln=%%A"
if not defined replace (
echo(%%A
setlocal enableDelayedExpansion
if "!ln:<appSettings>=!" neq "!ln!" (
endlocal
set replace=1
) else endlocal
) else (
setlocal enableDelayedExpansion
if "!ln:</appSettings>=!" equ "!ln!" (
endlocal
for /f tokens^=2^ delims^=^" %%K in ("%%A") do set "$%%K=%%A"
) else (
endlocal
for /f "delims=" %%B in (file1.txt) do for /f tokens^=2^ delims^=^" %%K in ("%%B") do set "$%%K=%%B"
for /f "tokens=1* delims==" %%B in ('set $') do echo(%%C
echo(%%A
set "replace="
)
)
)
)
move /y file2.txt.new file2.txt >nul
以下是基于原始问题中的这些file1.txt和file2.txt规范的原始答案:
File1.txt(参考文件)
<add key="abc" value="123" />
<add key="def" value="456" />
<add key="ghi" value="789" />
File2.txt(目标文件)
<add key="def" value="blank" />
<add key="ghi" value="blank" />
我假设您文件中的所有行都与您显示的模板匹配(除了使用普通的双引号而不是智能引号,正如Magoo指出的那样)。我还假设最终输出中的行顺序无关紧要,并且键不区分大小写。
假设密钥不包含空格。标签或反斜杠,然后:
@echo off
>file1.txt.screen (for /f "tokens=2" %%A in (file1.txt) do echo( %%A )
>file2.txt.new (
findstr /livg:file1.txt.screen file2.txt
type file1.txt
)
del file1.txt.screen
move /y file2.txt.new file2.txt >nul
如果键可能包含空格或制表符,但不包含反斜杠,则:
@echo off
>file1.txt.screen (for /f tokens^=2^ delims^=^" %%A in (file1.txt) do echo( key="%%A" )
>file2.txt.new (
findstr /livg:file1.txt.screen file2.txt
type file1.txt
)
del file1.txt.screen
move /y file2.txt.new file2.txt >nul
如果键可能包含空格或制表符或反斜杠,则:
@echo off
setlocal disableDelayedExpansion
>file1.txt.screen (
for /f tokens^=2^ delims^=^" %%A in (file1.txt) do (
set "key=%%A"
setlocal enableDelayedExpansion
(echo( key="!key:\=\\!" )
endlocal
)
)
>file2.txt.new (
findstr /livg:file1.txt.screen file2.txt
type file1.txt
)
del file1.txt.screen
move /y file2.txt.new file2.txt >nul
由于此FINDSTR错误,以上所有解决方案在查找密钥时都必须执行不区分大小写的搜索:Why doesn't this FINDSTR example with multiple literal search strings find a match?
<强>更新强>
以下是一个不区分大小写的解决方案,它消除了所有限制。
@echo off
setlocal disableDelayedExpansion
for /f tokens^=2^ delims^=^" %%A in (file1.txt) do (
set "search= key="%%A" "
setlocal enableDelayedExpansion
(echo !search:\=\\!) >file2.txt.screen
findstr /vlg:file2.txt.screen file2.txt >file2.txt.new
move /y file2.txt.new file2.txt >nul
endlocal
)
type file1.txt >>file2.txt
del file2.txt.screen