使用文件名作为属性值搜索和替换XML属性(Powershell或批处理文件)
我需要帮助来查找并替换一个属性“parentid”,该属性在文件夹中的每个XML文件中都有“00000000-0000-0000-0000-000000000000”。没有扩展名的每个文件的实际文件名应替换XML中的“parentid”属性。(Powershell或批处理文件) 例如:C:\Folder\使用文件名作为属性值搜索和替换XML属性(Powershell或批处理文件),xml,loops,powershell,batch-file,replace,Xml,Loops,Powershell,Batch File,Replace,我需要帮助来查找并替换一个属性“parentid”,该属性在文件夹中的每个XML文件中都有“00000000-0000-0000-0000-000000000000”。没有扩展名的每个文件的实际文件名应替换XML中的“parentid”属性。(Powershell或批处理文件) 例如:C:\Folder\ 4de6d1b4-b014-4cb3-bb61-649737a8217b.xml 4d2345b4-b415-5656-12dv-832jnm89234n.xml XML的内容: &l
4de6d1b4-b014-4cb3-bb61-649737a8217b.xml
4d2345b4-b415-5656-12dv-832jnm89234n.xml
XML的内容:
<comment id="4de6d1b4-b014-4cb3-bb61-649737a8217b" parentid="00000000-0000-0000-0000-000000000000" approved="True">
<date>2014-12-20 22:23:40</date>
<author>Joe Doe</author>
<email>test@example.com</email>
<country />
<ip>0.0.0.0</ip>
<avatar />
<content>Test</content>
</comment>
在PowerShell中加载/解析XML文件的示例很多,但在这种简单的情况下,最快的解决方案是对包含整个文件的字符串使用纯文本搜索/替换:
$searchFor = 'parentid="00000000-0000-0000-0000-000000000000"'
Get-ChildItem -Literal 'c:\folder' -Filter '*.xml' -Recurse |
Where {
Select-String $searchFor -Path $_ -CaseSensitive -SimpleMatch
} |
ForEach {
$text = [IO.File]::ReadAllText($_.FullName)
$text.replace($searchFor, 'parentid="' + $_.BaseName + '"') |
Out-File (Join-Path $_.Directory "$($_.BaseName)-new.xml") -Encoding utf8
}
基本问题是,您引用的是一个
for
变量,即%%p
,不在循环范围内,我不建议这样做
使用纯批处理脚本,我会将您的代码更改为:
@echo关闭
setlocal EnableExtensions DisableDelayedExpansion
设置“搜索=00000000-0000-0000-0000-000000000000”
对于“*.xml”中的%%P,请执行以下操作(
对于/F“delims=”%%I in('
findstr/N/R“^”“%%~P”^&^>“%%~fP”中断
""做"(
设置“行=%%I”
setlocal EnableDelayedExpansion
设置“行=!行:*=!”
如果定义了行集“行=!行:%SEARCH%=%%~nP!”
>>“%%~fP”回显(!行!
端部
)
)
端部
退出/B
这可以直接修改当前目录中枚举的*.xml
文件,因此不需要临时文件来替换属性parentid
每个文件都由
findstr
读取,它在每一行前面临时加上行号和冒号,以避免丢失空行(请记住,for/F
忽略了这一点)。命令行set“line=!line:=!”
随后删除前缀。请注意,for/F
中的延迟扩展被切换,以避免丢失文件中出现的任何感叹号。这些措施确保原始*.xml
文件内容不会被更改,当然被替换的部分除外。似乎-Raw模式不起作用对我来说,因为我有PS v2。我得到:得到内容:找不到与-Raw匹配的参数。如果我是v2,我该怎么做。抱歉,我对此有点陌生。使用(得到内容-Raw$\全名)
而不是[IO.File]::ReadAllText($\全名)
。问题是我几年前切换到PS4.0,所以我很难一直思考PS2的存在。不过我会更新答案。它似乎没有处理所有文件。脚本运行时没有问题,但当我使用所有.xml检查文件夹时,似乎没有检查某些文件,但其他文件已正确完成。不确定原因在where子句中,我看到您有-CaseSensitive和-SimpleMatch…这是一个因素吗?我不是一个读心术的人。比较xml文件,看看有什么不同。
$searchFor = 'parentid="00000000-0000-0000-0000-000000000000"'
Get-ChildItem -Literal 'c:\folder' -Filter '*.xml' -Recurse |
Where {
Select-String $searchFor -Path $_ -CaseSensitive -SimpleMatch
} |
ForEach {
$text = [IO.File]::ReadAllText($_.FullName)
$text.replace($searchFor, 'parentid="' + $_.BaseName + '"') |
Out-File (Join-Path $_.Directory "$($_.BaseName)-new.xml") -Encoding utf8
}