【发布时间】:2019-01-10 20:51:40
【问题描述】:
我有一个包含结构化数据的文本文件(类似于 Json),我想用 ConvertFrom-String 解析它以提取部分数据。我无法更改文件中数据的结构方式,因此我必须按原样处理它们。
这是数据示例。完整的文件包含更多这些块,并且每个块的“属性”都比我在这里展示的要多(保持小而易读:-))。请注意,第三个块为 icon 属性,其他项目没有。
$Data = @'
c_first_item = {
time = 270
category = cat_red
min_value = {
int = 10
}
max_value = {
int = 20
}
}
c_second_item = {
time = 270
category = cat_blue
min_value = {
float = 10
}
max_value = {
float = 20
}
}
c_third_item = {
time = 270
icon = c_third_icon
category = cat_red
min_value = {
int = 10
}
max_value = {
int = 20
}
}
'@
这是 ConvertFrom-String 使用的我的模板。
$Template = @'
{Name*:c_first_item} = \{
time = 270
category = {Category:cat_red}
random_property = \{
random_property_value = 10
\}
random_property = \{
random_property_value = 20
\}
\}
{Name*:c_second_item} = \{
time = 100
icon = {Picture?:c_third_icon}
category = {Category:cat_blue}
random_property = \{
random_property_value = 10
\}
random_property = \{
random_property_value = 20
\}
\}
'@
我用ConvertFrom-String 运行这段代码来解析我想要的数据:
$Result = $Data | ConvertFrom-String -TemplateContent $Template
预期的结果应该是这样的:
Name Category Picture
---- -------- -------
c_first_item cat_red
c_second_item cat_blue
c_third_item cat_red c_third_icon
但我却得到了这个:
Name Category
---- --------
c_first_item cat_red
c_second_item cat_blue
c_third_item cat_red
如您所见,我的输出对象中没有Picture 属性,因为ConvertFrom-String 无法根据我的要求解析数据。我想我给出的例子不足以教算法如何反应。
有没有办法让我教ConvertFrom-String 为不存在icon 的块获取一个空的Picture 属性?
更新:1 月 25 日
根据@iRon 的要求,这是一个将Length 属性添加到结果的示例。
首先,我正在解析的文件(Test.txt):
d_mem_towers_sulfuric_forest = {
is_for_colonizeable = yes
category = deposit_cat_rare
icon = d_radioactive_wasteland
resources = {
category = planet_deposits
produces = {
society_research = 4
energy = 4
}
}
planet_modifier = {
planet_jobs_energy_produces_mult = 0.10
planet_jobs_society_research_produces_mult = 0.10
planet_max_districts_add = -1
pop_environment_tolerance = -0.15
}
drop_weight = {
weight = 0
}
}
然后,模板文件(Template.txt):
{Object*:{Name:d_mem_sadrell_capital} = \{
is_for_colonizeable = yes
category = {Category:deposit_cat_rare}
icon = {Picture:d_building}
planet_modifier = \{
planet_housing_add = 3
pop_environment_tolerance = 0.1
planet_jobs_specialist_produces_mult = 0.15
\}
triggered_planet_modifier = \{
potential = \{
exists = owner
owner = \{ is_regular_empire = yes \}
\}
modifier = \{
job_researcher_add = 2
job_clerk_add = 2
\}
\}
triggered_planet_modifier = \{
potential = \{
exists = owner
owner = \{ is_hive_empire = yes \}
\}
modifier = \{
job_brain_drone_add = 2
job_maintenance_drone_add = 2
\}
\}
triggered_planet_modifier = \{
potential = \{
exists = owner
owner = \{ is_machine_empire = yes \}
\}
modifier = \{
job_calculator_add = 2
job_maintenance_drone_add = 2
\}
\}
drop_weight = \{
weight = 0
\}
\}}
{Object*:{Name:d_mem_sadrell_industrial_complex} = \{
is_for_colonizeable = yes
category = {Category:deposit_cat_rare}
icon = {Picture:d_crater}
planet_modifier = \{
pop_environment_tolerance = -0.1
planet_jobs_minerals_produces_mult = 0.25
district_mining_max = 4
\}
drop_weight = \{
weight = 0
\}
\}}
{Object*:{Name:_mem_strange_mountain} = \{
time = 365
is_for_colonizeable = yes
category = {Category:deposit_cat_blockers}
icon = {Picture:d_mem_strange_mountain}
resources = \{
category = deposit_blockers
cost = \{
energy = 1000
minerals = 1000
\}
\}
drop_weight = \{
weight = 0
\}
\}}
最后,这是我用来提取数据的一段代码:
$testText = Get-Content -Path "Path\to\text.txt" #MEM
$template = 'Path\to\template.txt'
$result = $testText |
ConvertFrom-String -TemplateFile $template |
Select-Object -ExpandProperty Object |
Union-Object
$result
预期的结果应该是这样的:
Name Category Picture
---- -------- -------
d_mem_towers_sulfuric_forest deposit_cat_rare d_radioactive_wasteland
但我得到了这个:
Name Category Picture Length
---- -------- ------- ------
d_mem_towers_sulfuric_forest deposit_cat_rare d_radioactive_wasteland
0
我的对象的第二行包含我不解析的Length 属性,所以我猜它以某种方式来自Union-Object。
有什么想法吗?
【问题讨论】:
-
试试:
$Result |Union-Object -
@iRon :这个函数无法帮助我得到解析不首先返回的结果。或者有什么我不明白的。 :)
-
从更新:1 月 25 日开始解决问题:从
$Result中删除| Union-Object。而是将其转换为 JSON ($Result | ConvertTo-Json) 或 PowerShell 表达式 ($Result |ConvertTo-Expression) 并注意流末尾的空字符串。这是导致结果中长度属性类似于:"" | Union-Object(另请参见:"" | Get-Member -Type Property)的原因。 -
您还可以通过
$result | %{$_.GetType()}查看不同的输出类型。无论如何,解决方案是仅包含包含某些内容的对象 (... | Where-Object {$_} | Union-Objec) 或仅从对象列表中排除字符串 (... | Where-Object {$_ -isNot [String]} | Union-Object)。 -
感谢您抽出宝贵时间@iRon。看起来
SelectFrom-String以某种方式生成了不需要的数据。我会按照你的建议简单地过滤它们,这样它们就不会再打扰我了。 :)
标签: powershell