搜索xml文件并替换其中的字符串
我正在尝试在Windows 7中创建一个批处理文件,以帮助我删除Skype广告 以下是我到目前为止的收获:搜索xml文件并替换其中的字符串,xml,powershell,Xml,Powershell,我正在尝试在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%
@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
@echo关闭
回显编辑“%WINDIR%\System32\Drivers\Etc\Hosts”文件
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
回显编辑“%APPDATA%\Skype”配置
powershell-Command“(Get-ChildItem%APPDATA%\Skype-Filter“config.xml”-Recurse)| ForEach对象{$\替换'1',0'}|设置内容$\
ipconfig/flushdns
暂停
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
编辑'C:\Users\user\AppData\Roaming\Skype'配置
Set Content:无法将参数绑定到参数“Path”,因为它为null。
第1行字符:218
+(Get ChildItem C:\Users\user\AppData\Roaming\Skype-Filter config.xml-Recurse)| ForEach对象{$\替换'1
“,“0”}设置内容>%WINDIR%\System32\Drivers\Etc\Hosts
echo 127.0.0.1 g.msn.com>%WINDIR%\System32\Drivers\Etc\Hosts
回显编辑“%APPDATA%\Skype”配置
powershell-noprofile-c“$files=Get ChildItem$env:AppData\Skype-Recurse config.xml;foreach($files中的文件){(Get Content$file.fullname)-替换“1”、“0”|设置Content$file.fullname}”
ipconfig/flushdns
回音完毕。请重新启动Skype以使更改生效。
暂停
在撰写本文时已确认工作。您有几个问题,我认为您走错了方向<代码>设置内容接受管道输入并将其发送到文件。在大多数情况下,需要使用
-path
(或按位置)指定其路径。前面的另一个问题是,您没有实际读取找到的文件。您当前的代码正试图操纵文件名本身,这不是您想要的
与您正在寻找的内容更接近的是:
powershell -Command "$file = Get-ChildItem %APPDATA%\Skype -Filter 'config.xml' -Recurse | Select -First 1 -ExpandProperty FullName; (Get-Content $file) | ForEach-Object { $_.replace('<AdvertPlaceholder>1</AdvertPlaceholder>', '<AdvertPlaceholder>0</AdvertPlaceholder>')} | Set-Content $file"
如果您需要帮助运行脚本
我认为只有config.xml存在。如果您想编辑所有配置文件,那么几乎不需要更改。不过这次我们需要确保要编辑的值退出。因为config.xml不是唯一的名称
# Locate and read the config.xml documents. Use object notation to find the node we need to change to 0 then save the file.
$configPaths = Get-ChildItem "$($env:appdata)\Skype" -Filter "config.xml" -Recurse | Select-Object -ExpandProperty FullName
# Cycle each file found
$configPaths | ForEach-Object{
$xml = [xml](Get-Content $_)
if($xml.config.UI.General.AdvertPlaceholder){
# Check to be sure this value actually is present before we try to change it.
$xml.config.UI.General.AdvertPlaceholder = "0"
# Only need to save if change was made.
$xml.Save($_)
}
}
首先,我建议在PowerShell中完成这一切,这最终简化了问题:
撇开处理两种截然不同的环境的复杂性不谈,使用
PowerShell-command
调用PowerShell命令和包含要执行的命令的命令字符串会引入引用复杂性,这可能很难解决
其次,您的问题是您的管道试图同时执行两个不同的操作:
- 传递文件的路径
- 同时也转换该文件的内容
设置内容
要写回哪些文件
虽然可以使用单个管道执行此操作,但实际上无法读取,因此我建议分步骤执行这两个任务:
注意:我知道您的Get ChildItem
命令实际上只会生成一个文件,但可能会生成多个文件,因此我将尝试解决这种情况。此外,我还避免使用
cmd.exe
变量(%AppDate%
),而只使用PowerShell($env:AppData
)。另外,请注意在下面的正则表达式中使用了反向引用(
\1
),这避免了重复广告占位符
,也避免了在替换表达式中使用$1
来引用正则表达式中的第一个捕获组(广告占位符
)
如果我们现在只关注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
}
设置内容需要文件名…我最终使用了您的方法,因为您不排除任何其他config.xml文件,这与@Matt不同。虽然目前在
…\Skype\…
下的文件夹中只有一个配置文件,但如果Skype在不同的文件夹下获得更多配置文件,即使脚本不会中断。我将对此给予肯定,在编辑XML时,您的答案包含更多细节。谢谢大家!@S.T.A.L.K.E.R。如果需要,更新逻辑以允许多个文件。我只是阻止了这一点,因为我没想到会有多个skype配置文件,但很可能存在多个配置文件,并希望防止出现错误。
# Locate and read the config.xml documents. Use object notation to find the node we need to change to 0 then save the file.
$configPaths = Get-ChildItem "$($env:appdata)\Skype" -Filter "config.xml" -Recurse | Select-Object -ExpandProperty FullName
# Cycle each file found
$configPaths | ForEach-Object{
$xml = [xml](Get-Content $_)
if($xml.config.UI.General.AdvertPlaceholder){
# Check to be sure this value actually is present before we try to change it.
$xml.config.UI.General.AdvertPlaceholder = "0"
# Only need to save if change was made.
$xml.Save($_)
}
}
$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
}
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 }"