我有一个文本文件“list.txt”,其中包含要解析的数百个URL列表,以及一些通用配置数据,使用“list.txt”中的每个值解析为单个xml文件(配置文件) ”,就像这样:
list.txt包含:
line_1
line_2
line_3
样板配置数据如下所示(以
line_1
为例):<?xml version="1.0"?>
<Website xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Url>line_1.mydomain.com</Url>
<Title>line_1</Title>
<Enabled>true</Enabled>
<PluginInName>Tumblr</PluginInName>
</Website>
因此,如果“list.txt”包含100个项目,我希望100个配置文件分别与
URL
和Title
元素一起编写。在阅读数组和创建文本文件时,我迷糊了几篇文章,但是我无法使其工作。
我尝试过的方法,尽管目前还不成熟。我不确定我从哪里开始或如何到达这里:
$FileName = "C:\temp\list.txt"
$FileOriginal = Get-Content $FileName
# create an empty array
Foreach ($Line in $FileOriginal)
{
$FileModified += $Line
if ($Line -match $pattern)
{
# Add Lines after the selected pattern
$FileModified += 'add text'
$FileModified += 'add second line text'
}
}
Set-Content $fileName $FileModified
这是超越我新手Powershell技能的。有人可以帮忙吗?
最佳答案
您正在寻找一种字符串模板化方法,其中使用当时最新的变量值按需实例化引用变量的字符串模板:
# Define the XML file content as a *template* string literal
# with - unexpanded - references to variable ${line}
# (The {...}, though not strictly necessary here,
# clearly delineates the variable name.)
$template = @'
<code>
<?xml version="1.0"?>
<Website xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Url>${line}.mydomain.com</Url>
<Title>${line}</Title>
<Enabled>true</Enabled>
<PluginInName>Tumblr</PluginInName>
</Website>
'@
# Loop over all input lines.
Get-Content C:\temp\list.txt | ForEach-Object {
$line = $_ # store the line at hand in $line.
# Expand the template based on the current $line value.
$configFileContent = $ExecutionContext.InvokeCommand.ExpandString($template)
# Save the expanded template to an XML file.
$configFileContent | Set-Content -Encoding Utf8 "$line.xml"
}
笔记:"$line.xml"
,即为每个输入行命名它们并将它们存储在当前位置;根据需要进行调整。$ExecutionContext
来完成的,该模板的.InvokeCommand
属性提供对 .ExpandString()
方法的访问,该允许按需执行字符串扩展(插值),就像输入字符串是双引号字符串一样-请参见this answer有关详细示例。$ExecutionContext.InvokeCommand.ExpandString()
cmdlet以更容易发现的方式显示Expand-String
方法的功能是this GitHub feature request的主题。 Ansgar Wiechers指出,在这种简单情况下,考虑到模板扩展过程中仅传递一条信息,在这种简单情况下,可以使用更简单的替代来替代,请使用PowerShell的string-formatting operator,
-f
来填充模板:# Define the XML file content as a *template* string literal
# with '{0}' as the placeholder for the line variable, to
# be instantiated via -f later.
$template = @'
<code>
<?xml version="1.0"?>
<Website xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Url>{0}.mydomain.com</Url>
<Title>{0}</Title>
<Enabled>true</Enabled>
<PluginInName>Tumblr</PluginInName>
</Website>
'@
# Loop over all input lines.
Get-Content C:\temp\list.txt | ForEach-Object {
# Expand the template based on the current $line value.
$configFileContent = $template -f $_
# Save the expanded template to an XML file.
$configFileContent | Set-Content -Encoding Utf8 "$line.xml"
}
可选阅读:在
-f
和$ExecutionContext.InvokeCommand.ExpandString()
之间进行选择以进行模板扩展:向安斯加尔求助。
使用
-f
:{0:N2}
格式化带两位小数位的数字)。-f
占位符总是位置和抽象的。例如,{2}
只是告诉您您正在使用第3个占位符,而没有告诉您有关其目的的任何信息;在具有多个占位符的较大模板中,这可能会成为一个问题。使用
$ExecutionContext.InvokeCommand.ExpandString()
:$ExecutionContext.InvokeCommand.ExpandString()
将安静地忽略模板中引用的不存在的变量-可能需要也可能不需要。Set-StrictMode -Version 2
或更高版本来报告错误。通常,使用Set-StrictMode
是一个好习惯,不过请注意,它的作用是isn't lexically scoped,并且可以disable convenient functionality。