我有一个文本文件“ list.txt”,其中包含我要解析的数百个URL列表,以及一些通用配置数据,使用“ list.txt”,就像这样:
list.txt包含:
line_1
line_2
line_3
样板配置数据如下(以“ line_1”为例):
<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_1.mydomain.com</Url>
<Title>line_1</Title>
<Enabled>true</Enabled>
<PluginInName>Tumblr</PluginInName>
</Website>
因此,如果“ list.txt”包含100个项目,我希望100个配置文件分别由<i> 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技能方式。有人可以帮忙吗?
答案 0 :(得分:3)
您正在寻找一种字符串模板化方法,其中使用当时的变量值按需实例化引用变量的字符串模板:
# 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"
}
注意:
我为输出XML文件选择了UTF-8编码,并将其命名为"$line.xml"
,即为每个输入行命名并将它们存储在当前位置;根据需要进行调整。
via automatic variable $ExecutionContext
执行模板扩展(插值),其.InvokeCommand
属性提供对 .ExpandString()
方法的访问,允许按需执行字符串扩展(插值),就像输入字符串是双引号字符串一样-有关详细示例,请参见this answer。
Ansgar Wiechers指出,在这种简单情况下,更简单的选择-假定在模板扩展期间仅传递单个一条信息- strong>使用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()
之间进行模板扩展:
向Ansgar求助的帽子提示。
使用-f
:
优点:
在调用时明确指出将要填充哪些值。
此外,在占位符中包含格式设置指令也更容易(例如,{0:N2}
用于格式化带小数点后两位的数字)。
显式传递值可以轻松地在不同范围内重用模板。
如果您不小心传递了太少或太多的值,默认情况下将发生错误。
缺点:
-f
占位符总是位置和抽象;例如,{2}
只是告诉您您正在处理 3rd 占位符,而没有告诉您有关其目的的任何信息;在具有多个占位符的较大模板中,这可能会成为问题。
即使您传递了正确数量的值,它们也可能以错误的顺序排列,这可能导致细微的错误。
使用$ExecutionContext.InvokeCommand.ExpandString()
:
优点:
如果变量具有描述性名称,则模板将更具可读性,因为占位符(变量名称)将指示其用途。
无需在调用时显式传递值-扩展仅依赖于当前作用域中可用的变量。
缺点:
如果您在多个功能(作用域)中使用模板,则需要确保在模板中引用的变量均已设置。
至少在默认情况下,$ExecutionContext.InvokeCommand.ExpandString()
会静默忽略模板中引用的不存在的变量-可能需要也可能不需要。
Set-StrictMode -Version 2
或更高版本来报告错误;使用Set-StrictMode
通常是一个好习惯,不过请注意,其效果isn't lexically scoped可以disable convenient functionality。通常,您需要手动将模板与设置模板中引用的变量的代码保持同步,以确保将正确的值填充(例如,如果引用的变量的名称更改了, ,模板字符串也必须更新)。