gpt4 book ai didi

xml - 搜索 xml 文件并替换其中的字符串

转载 作者:数据小太阳 更新时间:2023-10-29 02:26:00 25 4
gpt4 key购买 nike

我正在尝试在 Windows 7 中创建一个批处理文件来帮助我删除 Skype 广告。

到目前为止,这是我带来的:

@echo off

echo Editing '%WINDIR%\System32\Drivers\Etc\Hosts' file
echo 127.0.0.1 apps.skype.com >> %WINDIR%\System32\Drivers\Etc\Hosts
echo 127.0.0.1 g.msn.com >> %WINDIR%\System32\Drivers\Etc\Hosts

echo Editing '%APPDATA%\Skype' config
powershell -Command "(Get-ChildItem %APPDATA%\Skype -Filter "config.xml" -Recurse) | ForEach-Object { $_ -replace '<AdvertPlaceholder>1</AdvertPlaceholder>', '<AdvertPlaceholder>0</AdvertPlaceholder>' } | Set-Content $_"

ipconfig /flushdns

pause

powershell 命令抛出一个错误:

Editing 'C:\Users\user\AppData\Roaming\Skype' config
Set-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:1 char:218
+ (Get-ChildItem C:\Users\user\AppData\Roaming\Skype -Filter config.xml -Recurse) | ForEach-Object { $_ -replace '<AdvertPlaceholder>1</AdvertPlaceholder>
', '<AdvertPlaceholder>0</AdvertPlaceholder>' } | Set-Content <<<< $_
+ CategoryInfo : InvalidData: (:) [Set-Content], ParameterBinding
ValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetContentCommand

我做错了什么?如何将内容设置为 Get-ChildItem 找到的文件?如果您有其他方法,我也想听听。非常感谢。

编辑:

这是我最终使用的:

@echo off

echo Editing '%WINDIR%\System32\Drivers\Etc\Hosts' file
echo 127.0.0.1 apps.skype.com >> %WINDIR%\System32\Drivers\Etc\Hosts
echo 127.0.0.1 g.msn.com >> %WINDIR%\System32\Drivers\Etc\Hosts

echo Editing '%APPDATA%\Skype' config
powershell -noprofile -c "$files = Get-ChildItem $env:AppData\Skype -Recurse config.xml; foreach($file in $files) { (Get-Content $file.fullname) -replace '<(AdvertPlaceholder)>1</\1>', '<$1>0</$1>' | Set-Content $file.fullname }"

ipconfig /flushdns

echo Done. Please restart Skype for changes to take effect.

pause

确认在撰写本文时工作。

最佳答案

首先,我建议在 PowerShell 中全部完成,这最终会简化事情:
撇开处理 2 个截然不同的环境的复杂性不谈,使用 powershell -command 调用 PowerShell 命令和包含要执行的命令的命令字符串引入了引用复杂性,这可能很难解决。

其次,您的问题是您的管道试图同时做 2 件不同的事情:

  • 通过文件的路径传递
  • 同时还转换该文件的内容

您的尝试混淆了这两项任务:它传入文件对象(在字符串上下文中解析为它们的路径),然后错误地将它们视为它们的内容,然后神奇地期望修改后的内容变回文件对象(路径),告诉 Set-Content 要写回哪些文件。

虽然可以通过单个管道完成此操作,但它实际上是不可读的,因此我建议在单独的步骤中执行这两项任务:

注意:我知道您的 Get-ChildItem 命令实际上只会产生 1 文件,但可能它会产生多个,所以我会尝试解决这个问题。
此外,我避免使用 cmd.exe 变量 (%AppDate%),而是仅使用 PowerShell 的 ($env:AppData) .
另外,请注意在下面的正则表达式中使用了 反向引用 (\1),这避免了重复 AdvertPlaceholder 的需要,因为以及在替换表达式中使用 $1 来引用正则表达式中的第一个捕获组 (AdvertPlacholder)

如果我们现在只关注 PowerShell,我们会得到:

$files = Get-ChildItem $env:AppData\Skype -Recurse config.xml
foreach($file in $files) {
(Get-Content $file.fullname) -replace '<(AdvertPlaceholder)>1</\1>', '<$1>0</$1>' |
Set-Content $file.fullname
}

注意:

  • 在字符编码方面,Set-Content默认为系统默认的代码页。如有疑问,请使用显式编码,例如 -Encode UTF8

  • 上面假设所讨论的 XML 元素位于单个 行中。如果不是,事情会变得更加复杂:虽然您可以使用 Get-Content -Raw (PowerShell v3+) 一次读取整个输入文件,但是 Set-Content将在输出中添加一个额外的换行符;此外,您还必须修改传递给上面的 -replace 的正则表达式,以解决跨行空白问题。

    • Matt's helpful answer显示了一种更稳健的处理值替换的方法,通过[xml] 类型使用正确的 XML 解析(完全限定名称:System.Xml.XmlDocument).

如果您仍想从批处理 文件中调用上述 PowerShell 命令,请按以下步骤操作:

请注意,需要使用单行 文字传递给powershell.exe -command,这使得整个内容不可读;此外,添加 -noprofile 通常是一个好主意,以抑制配置文件的加载,该文件仅供交互式使用。

 powershell -noprofile -command "$files = Get-ChildItem $env:AppData\Skype -Recurse config.xml; foreach($file in $files) { (Get-Content $file.fullname) -replace '<(AdvertPlaceholder)>1</\1>', '<$1>0</$1>' | Set-Content $file.fullname }"

关于xml - 搜索 xml 文件并替换其中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34446275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com