我想制作一个Powershell脚本,以使更改多个文件中的行变得更快。
这真的是我第一次尝试做这样的事情。我基本上想做的是:
<package>true</package>
)/<package>false</package>
:)。此外,如果文件不包含,<package>true</package>
我也想添加<package>false</package>
我以前从未真正使用过powershell,所以我做了一些挖掘并想出了这段代码:
$files = Get-ChildItem –Path 'C:\test-XML\XML' -Recurse -Filter *.xml
$tempFilePath = 'C:\test-XML\newXml'
$find = '<packag>true</package>'
$replace = '<packag>false</package>'
foreach ($f in $files){
(Get-Content $f) -replace $find, $replace | Add-Content -Path $tempFilePath
}
使用此代码,我应该能够获取目录中的所有文件,然后循环通过该目录并使用更新的文本来更改文本。但这是行不通的,也没有涵盖使任务简化所需的所有要点。
有没有人有见识可以使它工作,甚至可以使其比现在更好。
一般来说,它的价值抽穗灌浆zett42的建议:处理XML文件,它是更强大的使用专用的XML解析器,特别是[xml]
(System.Xml.XmlDocument
)。
如果纯文本处理是一个选项-它听起来就像是给你的-你可以用下面的办法,这将更新所有文件到位; 它针对性能进行了优化:
Get-ChildItem –LiteralPath C:\test-XML\XML -Recurse -Filter *.xml |
ForEach-Object {
# CAUTION: This updates files *in place*.
# Adjust the encoding as needed.
Set-Content -Encoding Utf8 $_.FullName -Value (
(Get-Content -Raw $_.FullName) -replace '<package>true</package>', '<package>false</package>'
)
}
笔记:
你的代码的主要问题大概只是一个错字:<packag>
-> <package>
。
文件内容会在适当位置更新,因此为了安全起见,最好先备份文件。如果写回更新内容的过程被中断,则存在文件损坏的假想风险。
为了提高效率,读取整个文件到一个单一的,多行字符串(默认行为是,以输出阵列的线,这是很慢),从而只有单个操作是必要的。如果输入字符串中没有匹配项,则按原样返回。Get-Content
-Raw
-replace
需要注意的是PowerShell中始终使用文件写小命令的默认输出字符编码,而不管编码的输入文件的用途,因此,明确使用Set-Content
的
-Encoding
参数。
请注意,更新后的内容将传递给Set-Content
-Value
参数,而不是通过管道($content | Set-Content ...
);尽管此处的性能几乎没有差别,但假设只传递一个字符串,并进行行数组处理,则它将:如果,例如,$content
包含要写入文件的行数组,Set-Content ... -Value $content
其速度将比$content | Set-Content ...
为简便起见,Set-Content
andGet-Content
调用按位置传递filename参数,该-Path
参数隐式绑定到该参数,严格来说,该参数接受通配符模式;通常,即使你传递文字文件名也可以按预期工作,但是更健壮的方法是使用-LiteralPath
参数,如Get-ChildItem
上面的调用所示;具体来说,包含[
且]
导致-Path
参数误解的文字文件名(除非已转义)。