Sorting PowerShell';s Sort Object cmdlet更改未排序的w.r.t.属性的顺序
我正在对一些XML进行排序,并希望根据一个特定的非唯一属性对元素进行排序,该属性允许我对类似的元素进行分组。在这些组中,我需要保持原始顺序。问题是,排序时,这些组内的顺序会发生变化,而重新排序时,顺序会再次发生变化。如果XML的内容没有改变,我需要一种不会改变任何东西的排序(否则SVN差异很难看)。以下是一个简化的示例:Sorting PowerShell';s Sort Object cmdlet更改未排序的w.r.t.属性的顺序,sorting,powershell,Sorting,Powershell,我正在对一些XML进行排序,并希望根据一个特定的非唯一属性对元素进行排序,该属性允许我对类似的元素进行分组。在这些组中,我需要保持原始顺序。问题是,排序时,这些组内的顺序会发生变化,而重新排序时,顺序会再次发生变化。如果XML的内容没有改变,我需要一种不会改变任何东西的排序(否则SVN差异很难看)。以下是一个简化的示例: $xml = [xml]@" <root> <element name="a" number="1" /> <element name="
$xml = [xml]@"
<root>
<element name="a" number="1" />
<element name="b" number="1" />
<element name="c" number="1" />
<element name="d" number="2" />
<element name="e" number="2" />
<element name="f" number="2" />
<element name="g" number="3" />
<element name="h" number="3" />
</root>
"@
Write-Host "`nFirst Sort produces this:"
$result1 = $xml.SelectNodes('//element') | Sort-Object -Property 'number'
Write-Host (($result1 | select -ExpandProperty 'number') + " <---Sorted on")
Write-Host (($result1 | select -ExpandProperty 'name') + " <---Order not maintained")
Write-Host "`nSorting the (already sorted) results of First Sort produces this:"
$result2 = $result1 | Sort-Object -Property 'number'
Write-Host (($result2 | select -ExpandProperty 'number') + " <---Sorted on")
Write-Host (($result2 | select -ExpandProperty 'name') + " <---Order changed again")
$xml=[xml]@”
"@
写入主机“`nFirst Sort生成以下结果:”
$result1=$xml.SelectNodes('//element')|排序对象-属性“number”
写入主机($result1 | select-ExpandProperty'number')+“对两个属性进行排序:
$xml.SelectNodes('//element') | Sort-Object -Property number, name
这将产生以下输出:
name number
---- ------
a 1
b 1
c 1
d 2
e 2
f 2
g 3
h 3
根据两个属性进行排序:
$xml.SelectNodes('//element') | Sort-Object -Property number, name
这将产生以下输出:
name number
---- ------
a 1
b 1
c 1
d 2
e 2
f 2
g 3
h 3
如果还没有表示自然排序顺序的内容,则可以使用add Member添加索引属性:
$nodes = @($xml.SelectNodes('//element'))
for ($i=0; $i -lt $nodes.Count; $i++)
{
$nodes[$i] = $nodes[$i] | Add-Member -MemberType NoteProperty "Index" $i -PassThru
}
$result1 = $nodes | Sort-Object name, Index
然后,无论您重新排序多少次,都可以保证获得相同的订单
更新:为PowerShell v2添加了语法如果您还没有表示自然排序顺序的内容,则只需添加带有add Member的索引属性:
$nodes = @($xml.SelectNodes('//element'))
for ($i=0; $i -lt $nodes.Count; $i++)
{
$nodes[$i] = $nodes[$i] | Add-Member -MemberType NoteProperty "Index" $i -PassThru
}
$result1 = $nodes | Sort-Object name, Index
然后,无论您重新排序多少次,都可以保证获得相同的订单
更新:为PowerShell v2添加了语法这并不能直接回答您的问题,但您可以对更多属性进行排序吗?例如,“排序对象编号,名称”不幸的是,不,这些是我需要保留原始顺序的属性(这些属性的顺序具有人类意义,这些是人们阅读/编辑的源文件).好问题。排序对象的文档中没有说明它在任何地方使用了稳定排序,因此没有理由期望它。我从来没有期望它是稳定排序,Joey,事实并非如此,所以我写了这个问题。这并没有直接回答你的问题,但你能按更多属性排序吗?例如,“排序对象编号、名称”“不幸的是,没有,这些是我需要保留的原始顺序(这些顺序具有人类意义,这些是人们阅读/编辑的源文件).好问题。排序对象
的文档没有说明它在任何地方使用了稳定排序,因此没有理由期望它。我从来没有期望它是稳定排序,Joey,事实并非如此,所以我写了这个问题。不幸的是,我需要保留名称属性的原始顺序,它可能不像示例中那样按字母顺序排列。Unf很可能我需要保留原始顺序名称属性,它可能不像示例中那样按字母顺序排列。我想这可能是我能做的最好的了。我希望不添加属性,但可能没有标准的排序机制来保持原始顺序。我将在本周尝试一下,然后标记答案。:)嗯,我无法使Add Member在System.Xml.XmlElement类型上工作。它不接收新成员。帮助文章说Add Member在“Windows PowerShell对象的实例”上工作,我想它不包括任意的.NET对象?我想我将不得不使用一个名称非常模糊的XML属性。这是一个黑客,但它应该工作。哎呀,我只测试了PowerShell v3预览版!显然,v3在列表处理方面更为自由。您可以在$xml周围添加“@()”。SelectNodes将结果解释为PowerShell列表。顺便说一句:add Member将自动用包含NoteProperty的PSObject包装.NET对象。我可能会使用$nodes | ForEach对象{$i=0}{$| add Member NoteProperty Index$i;$i++}
。另外请注意,除非需要特殊的字符串处理,否则不需要为cmdlet引用参数。我认为这可能是我能做的最好的了。我不希望添加属性,但可能没有标准的排序机制来保持原始排序。本周我将试一试,然后标出答案。:)嗯,我无法让Add Member处理System.Xml.xmlement类型。它不接收新成员。帮助文章说Add Member在“Windows PowerShell对象的实例”上工作,我想它不包括任意的.NET对象?我想我将不得不使用一个名称非常模糊的XML属性。这是一个黑客,但它应该工作。哎呀,我只测试了PowerShell v3预览版!显然,v3在列表处理方面更为自由。您可以在$xml周围添加“@()”。SelectNodes将结果解释为PowerShell列表。顺便说一句:add Member将自动用包含NoteProperty的PSObject包装.NET对象。我可能会使用$nodes | ForEach对象{$i=0}{$| add Member NoteProperty Index$i;$i++}
。还要注意,除非需要特殊的字符串处理,否则不需要为cmdlet引用参数。