gpt4 book ai didi

PowerShell - 为什么我的脚本使用默认类字段创建对象?

转载 作者:行者123 更新时间:2023-12-04 07:27:18 25 4
gpt4 key购买 nike

在我的脚本中,我试图从文本文件创建 PowerShell 对象。这是一个文本文件的示例。

junk data at the 

beginning of

the file


Item: Car
In Stock: YES
Make: Ford
Model: Taurus
Color: Blue
Miles: 0
Item: Car
Miles: 0
Item: Truck
Item: SUV
Item: Car
In Stock: YES
Make: Honda
Model: Civic
Color: Red
Miles: 0

junk
data at the

end
有时这些文件的开头和结尾都是垃圾数据。我尝试用我的 Select-String 语句来解决这个问题。
这是我的脚本:
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[string]$File
)

class Item {
[string] $Item = ''
[string] $Found = 'NO'
[string] ${In Stock} = 'N/A'
[string] $Make = 'N/A'
[string] $Model = 'N/A'
[string] $Color = 'N/A'
[string] $Miles = 'N/A'
}


[string[]]$Keep = @("Item:", "In Stock:", "Make:", "Model:", "Color:", "Miles:")

(Get-Content $File | Select-String -Pattern ($Keep -join "|") |
Out-String) -split '(?m)(?=^Item:)' -ne '' -replace '(?m)^(.+?):', '$1=' |
ConvertFrom-StringData | ForEach-Object {
$Obj = [Item] $_
if ($Obj.'In Stock' -eq 'Yes') {
$Obj.Found = 'YES'
}
Write-Output $Obj
}

该脚本的效果比它好得多。非常感谢另一位帮助我走到这一步的用户。
当我运行脚本时,我在顶部得到一个 EXTRA 对象,其中包含类中定义的所有默认值。这是为什么?
这是输出:
Item:
Found: NO
In Stock: N/A
Make: N/A
Model: N/A
Color: N/A
Miles: N/A

Item: Car
Found: YES
In Stock: YES
Make: Ford
Model: Taurus
Color: Blue
Miles: 0

Item: Car
Found: NO
In Stock: N/A
Make: N/A
Model: N/A
Color: N/A
Miles: 0

Item: Truck
Found: NO
In Stock: N/A
Make: N/A
Model: N/A
Color: N/A
Miles: N/A

Item: SUV
Found: NO
In Stock: N/A
Make: N/A
Model: N/A
Color: N/A
Miles: N/A

Item: Car
Found: YES
In Stock: YES
Make: Honda
Model: Civic
Color: Red
Miles: 0

最佳答案

您的 ForEach-Object 的输入电话在其中[Item] cast 发生(见下面的解释)以一个空行开始,这会产生一个额外的输出对象(具有所有类的默认值),因为它的作用类似于 [Item] @{} (因为类似 "`n" | ConvertFrom-StringData 输出一个空的哈希表),这反过来就像简单地调用(无参数默认)构造函数,[Item]::new() .
您可以按如下方式避免此空行(注意使用 .Line 并避免调用 Get-Content 以将文件路径直接传递给 Select-String ):

(
(Select-String -Pattern ($Keep -join "|") -LiteralPath $File).Line | Out-String
) -split '(?m)(?=^Item:)' -ne '' -replace '(?m)^(.+?):', '$1=' |
ConvertFrom-StringData | ForEach-Object {
$Obj = [Item] $_
if ($Obj.'In Stock' -eq 'Yes') {
$Obj.Found = 'YES'
}
Write-Output $Obj
}
空行(出现在开头和结尾)的原因是您直接发送 Select-String 的输出对象到 Out-String ,这会产生与您在控制台中看到的相同的显示字符串格式。访问 .Line属性(property)在 Select-String的输出对象避免了这种情况,因为它只输出字符串(而不是默认发出的 Microsoft.PowerShell.Commands.MatchInfo 实例),这不添加任何格式。
附注: Out-String出乎意料地总是在其输出字符串中附加一个尾随换行符; GitHub issue #14444 中讨论了这种有问题的行为.

[Item]的说明类型转换工艺:
关于类的实例化 [Item] ,属性具有类定义中指定的默认值,除非您稍后覆盖它们。
通过类型转换 hashtable - 作为 ConvertFrom-StringData 的输出- 至 [Item] ,其键与类的属性名称匹配的条目隐式设置这些属性;所有其他人保留其默认值(并且不允许使用与属性名称不匹配的键的条目)。
这种通过从哈希表进行转换的构造在 this answer 中有详细说明。 .

带有哈希表文字的简化示例 @{ ... } :
class Item {
$A = 'A_default'
$B = 'B_default'
$C = 'C_default'
}

# Construct an [Item] instance and assign to its .B property
[Item] @{ B = 'B_NEW' }
以上产生:
A         B     C
- - -
A_default B_NEW C_default

关于PowerShell - 为什么我的脚本使用默认类字段创建对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68146796/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com