【问题标题】:What is this powershell object? Array, hash, etc?这个 powershell 对象是什么?数组,哈希等?
【发布时间】:2014-12-22 08:54:58
【问题描述】:

我在脚本中有以下内容:

$Loc = Read-Host "Please select a location number"
$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"}
Foreach ($CIM in $ImpCSV) {$LocInfo = $CIM}

这似乎为 $Loc=1 创建了某种散列/数组/某个变量。如果我输入:

$LocInfo.add

它为我提供了该键的值(?),因为它应该在哈希表中,但如果我这样做:

$LocInfo

我明白了:

loc        :[1]
添加       :[一些值]

这不是通常的哈希输出。应该是这样的:

名称         值
----             -----
loc              [1]
添加           [一些值]

这首先导致我的问题是,如果我尝试使用$LocInfo.Set_Item("add", "HI") 编辑条目,它什么也不做。另外,我创建了一个表格来显示创建新对象的那些变量,但是如果没有给我一个语法错误,新的 -property 命令不会采用$LocInfo.add,返回一个"@{loc=1; add=some value}"。我必须做的是:

Set-Variable -Name add -Value $LocInfo.add

这组添加到[some value],然后我可以将它放在new-object 字段中,没有任何问题。

这也是有问题的,因为我的脚本会循环,因此他们可以添加另一个位置 (loc) 编号(比如说 2)并根据需要提取该位置的数据。如果他们正在搜索的新位置说缺少添加(地址),而不是创建一个空白 $LocInfo.add 然后是一个空白 $add,它会跳过它,这意味着当再次创建 new-object 时,它使用 $add从上一次运行,[一些值];即 loc 1 和 2 都具有相同的 $add 值。

我到底创造了什么,我该怎么做呢?有没有更好的方法从 CSV 文件中提取变量,不会像这样搞砸我?我打破了Powershell吗?我翻遍了,找不到这种变数的排列方式。

这是我尝试执行 Set_Item 时遇到的错误:

方法调用失败,因为 [System.Management.Automation.PSCustomObject] 不包含名为“Set_Item”的方法。
在 line:1 char:1
+ $LocInfo.Set_Item("add", "HI")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Set_Item:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

我使用New-Object 创建了对象,甚至这些对象都显示为哈希表,即根据对象大小具有标题和多个列。

【问题讨论】:

  • 在网上搜索了几个小时后,我开始自己回答了。

标签: arrays powershell csv hash


【解决方案1】:

第一件事:如果您不确定对象的类型,您可以使用GetType() 检查对象的类型。 Import-Csv 命令返回一个System.Object[],其中类似@{Letter="Test"}.GetType().FullName 的命令将返回System.Collections.Hashtable.FullName 仅返回我在这些示例中使用的字符串。

您似乎正在尝试使用Foreach ($CIM in $ImpCSV) {$LocInfo = $CIM} 这一行使用Where-Object 收集您的输出我看到的几个问题是您不断用$CIM 覆盖$LocInfo。在循环结束时,您将只有一个变量。如果您试图保留所有这些,则需要附加每个项目并将$LocInfo 声明为数组。

$LocInfo = @()
....
Foreach ($CIM in $ImpCSV) {$LocInfo += $CIM}

但除非您有更多未显示的代码,否则这似乎是多余的,因为您将使用相同的数据填充 $LocInfo$ImpCSV。您可以完全取消 for 循环并执行此操作。

$Loc = Read-Host "Please select a location number"
$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"}

除了删除最后一行,我什么都没做。

【讨论】:

  • 发生错别字。没什么大不了的。
  • 我试过这种方式,它确实生成了一个数组,但 $LocInfo[0] 给了我:
    loc : 1
    add : [somevalue]
    和 $LocInfo[ 1]什么也没给我。是的,我没有提供所有数据,因为它显示为列表的原因是因为我有大约 12 个条目。我希望 $LocInfo[0] 给我一个条目,[1] 给我第二个条目,等等..而不是这种方式 [0] 给我整个 psobject 作为一个列表,但我仍然可以做一个 $LocInfo。添加,我得到[一些价值]。是的,我可以看到创建 $ImpCSV 然后按照我目前拥有的方式执行 Foreach 是多余的,因为两者都是 PSobjects。
  • @user3377627 请在导入前使用文件中的一些示例数据更新您的帖子
  • @user3377627 以及该示例输入产生的输出。
【解决方案2】:

像这样将 import-csv 的结果转换为自定义对象有帮助吗?

$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"} | %{[pscustomobject]@{LOC=$_.LOC;ADD=$_.ADD}}

$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"} | %{new-object -TypeName PSCustomObject -Property @{LOC=$_.LOC;ADD=$_.ADD}}

【讨论】:

    【解决方案3】:

    Import-Csv 读取 CSV 文件并将其转换为以 CSV 列作为属性的自定义对象列表。但是,应该显示只有 2 个属性的对象in table format by default

    PS C:\> cat 'C:\test.csv'
    1,foo
    2,bar
    3,baz
    PS C:\> $csv = Import-Csv 'C:\test.csv' -Header loc,add | ? {$_.loc -eq '2'}
    PS C:\> $csv
    
    loc        add
    ---        ---
    2          bar

    如果您将对象通过管道传输到Format-List cmdlet,则只能以列表格式获得输出:

    PS C:\> $csv | Format-List
    
    loc : 2
    add : bar

    或者如果对象有 5 个或更多属性:

    PS C:\> cat 'C:\test2.csv'
    1,foo,a,a,a
    2,bar,b,b,b
    3,baz,c,c,c
    PS C:\> Import-Csv 'c:\test2.csv' -Header loc,add,f3,f4 | ? {$_.loc -eq '2'}
    
    loc        add        f3        f4
    ---        ---        --        --
    2          bar        b         b
    
    PS C:\> Import-Csv 'c:\test2.csv' -Header loc,add,f3,f4,f5 | ? {$_.loc -eq '2'}
    
    loc : 2
    add : bar
    f3  : b
    f4  : b
    f5  : b

    您可以对通常以列表格式显示的对象强制执行表格输出,方法是将它们传送到Format-Table cmdlet:

    PS C:\> Import-Csv 'C:\test2.csv' -Header loc,add,f3,f4,f5 |
    >> ? {$_.loc -eq '2'} | Format-Table
    >>
    
    loc        add        f3        f4        f5
    ---        ---        --        --        --
    2          bar        b         b         b

    不过,请注意,Format-ListFormat-Table 等格式化 cmdlet 用于显示数据。如果您想进一步处理对象,请不要使用它们。

    【讨论】:

      猜你喜欢
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 2016-06-01
      相关资源
      最近更新 更多