【问题标题】:Is the following possible in PowerShell: "Select-Object <Property>.<SubProperty>"?在 PowerShell 中是否可能:“Select-Object <Property>.<SubProperty>”?
【发布时间】:2015-06-18 04:25:50
【问题描述】:

场景:我正在使用 Select-Object 访问管道对象的属性,其中一个属性本身就是一个对象。我们称之为PropertyObject。我想访问该 PropertyObject 的一个属性,比如 Property1。是否有任何访问 Property1 的好方法和干净的方法,如下所示:

...| select-object PropertyObject.Property1

在进行实验时,只有执行以下操作才能使其正常工作:

...| select-object {$_.PropertyObject.Property1}

如果我想用一个像样的列名来显示它,它会变得更加混乱:

...| select-object @{Name="Property1"; Expression={$_.PropertyObject.Property1}}

鉴于 PowerShell 总体上是多么的简洁明了,我不禁想我遗漏了一些东西,应该有一种更简洁的方式来访问属性的属性。有吗?

编辑:按照马特的要求,这里是具体的例子:

我正在读取一个 XML 文件,Books3.xml:

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date inprint="false">2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
      <publisher>
        <name>Simon and Schuster</name>
        <country>USA</country>
        <city>New York</city>
      </publisher>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date inprint="true">2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
      <publisher>
        <name>HarperCollins</name>
        <country>USA</country>
        <city>New York</city>
      </publisher>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date inprint="false">2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
      <publisher>
        <name>Macmillan</name>
        <country>United Kingdom</country>
        <city>London</city>
      </publisher>
   </book>
</catalog>

将 XML 加载到 XmlDocument 中的代码:

$filePath = "C:\Temp\books3.xml"
$xmlDoc = new-object xml
$xmlDoc.load($filePath)

尝试阅读每本书的详细信息:

$xmlDoc.catalog.book | select author, title, publisher.name

结果:

author                     title                      publisher.name
------                     -----                      --------------
Gambardella, Matthew       XML Developer's Guide
Ralls, Kim                 Midnight Rain
Corets, Eva                Maeve Ascendant

【问题讨论】:

  • 你的 powershell 版本是什么?如果它是 3.0,您可以只使用 $object.PropertyObject.Property1,否则您只需链接选择 select PropertyObject | select Property1。您可能需要在其中进行一些扩展,但这就是要点。这一切都取决于道具
  • 我做了一个小更新,但我认为这不是您正在寻找的答案。提取单个属性比您要查找的对象输出更容易。 Select 是解决这个问题的方法。您可以通过将哈希移动到单个变量来清理它,但它不会更改所需的代码。

标签: powershell pipeline powershell-4.0


【解决方案1】:

您可以使用calculated properties。一个简短的形式将允许这样做:

$xmlDoc.catalog.book | select author, title, {$_.publisher.name}

如果属性名称很重要,您需要添加它们。

$xmlDoc.catalog.book | select author, title, @{N="PublisherName";E={$_.publisher.name}}

其中 N 是名称的缩写,E 是表达式的缩写。

【讨论】:

  • 这实际上回答了 OP 的问题。
【解决方案2】:

我也在寻找如何选择对象的子属性。在我的情况下,它是为了导出 DNS 服务器的区域数据。我将分享我用来实现目标的勇气,这里的帖子很有帮助!

要做你正在寻找的具体尝试修改你的代码如下:

$xmlDoc.catalog.book | Select Author, Title, -Expand Publisher | Select Author, Title, Name | Sort Author | FT -auto

根据您提供的表格输出,上述内容应该可以工作。它对我有用,您将在下面看到。

这个脚本非常适合我的需要,并且融合了不同的想法。希望它适用于其他人。

$Zones = @(Get-DnsServerZone)
ForEach ($Zone in $Zones) {
    Write-Host "`n$($Zone.ZoneName)" -ForegroundColor "Yellow"
    $Data = New-Object System.Object
    $Data = $Zone | Get-DnsServerResourceRecord
    $Data | Add-Member -MemberType NoteProperty -Name "ZoneName" -Value $Zone.ZoneName
    $Data += $Data
    $Data | Select-Object ZoneName, HostName, RecordType -Expand RecordData | Select ZoneName, HostName, RecordType, IPv4Address, HostNameAlias, NameServer, PrimaryServer, ExpireLimit, MinimumTimeToLive, RefreshInterval, ResponsiblePerson, RetryDelay, SerialNumber, DomainName, Port, Priority, Weight | Sort RecordType, HostName | Export-Csv -NoTypeInformation "$($Zone.ZoneName).csv"
}

当您在导出前查看输出时,黄色前景非常方便。只需将} 放在HostName 之后和| Export-Csv 之前,如下所示:... Sort RecordType, HostName }

【讨论】:

  • 试过了,但报错:Select-Object : A positional parameter cannot be found that accepts argument 'publisher'.不知道是不是因为书的对象是System.Xml.XmlElement类型?
【解决方案3】:

如果你有一些实际可重复的东西供我们测试会更容易,但我们可以通过Get-Items 返回来伪造它。

(Get-Item C:\temp\logoutput).Parent.Name

.Parent 实际上是一个System.IO.DirectoryInfo 对象。我使用 PowerShell 3.0 点符号来获取 nameparent

通过链接select 调用可以获得相同的结果

Get-Item C:\temp\logoutput | select -expand Parent | Select -Expand name

这当然可以在 PowerShell 2.0 中使用,但不是简洁的 3.0 版本。

发布问题编辑

不确定您希望得到什么。您所拥有的确实可以按照您拥有的方式提取子属性。我只能提供一种可能更直观、更友好但结果相同的替代方法。

$xml.catalog.book | ForEach-Object{
    $_ | Add-Member NoteProperty "PublisherName" $_.publisher.name -PassThru}

当然,您可能仍需要使用select 将输出限制为您需要的属性,但这是另一种选择。

【讨论】:

  • 我认为您的帖子问题编辑回答了我的问题:我不能做类似select author, title, publisher.name 的事情,我必须做一些更复杂的事情才能获得发布者的名称。我正在学习 PowerShell 的作用和不作用,而这正是我想知道的。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 2017-12-16
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多