我有一个powershell脚本,我将一组Conputernames分组并存储在一个哈希表中。到目前为止,Everithing工作正常。
$table = @{}
$pcs = "w7cl002","w7cl002","w7cl001","w7cl002","w7cl008", `
"w7lp001","w7lp001","w7cl008","w7cl004","w7lp001"
foreach ($pc in $pcs){
if ($table.Keys -notcontains $pc){
$Table.Add($pc,1)
}
else{
$occ = $table.get_item($pc) +1
$table.set_item($pc,$occ)
}
}
$table
这就是我想要的和我得到的。
Name Value
---- -----
stflw7lp001 3
stflw7cl002 3
stflw7cl004 1
stflw7cl001 1
stflw7cl008 2
最初,我想通过使用2D数组来实现这一目标。但经过5个小时的挣扎并将我的头靠在墙上,我放弃了,并用哈希表实现了它。
我只是想知道这是否可以使用2D数组?
答案 0 :(得分:3)
2D数组(在C#意义上,而不是Java意义上)在PowerShell中很蹩脚。我倾向于避开它们。它们也没有直接的语言支持,您必须使用New-Object
创建它们。
至于你的代码,你可以用这个来实现同样的目的:
$pcs = "w7cl002","w7cl002","w7cl001","w7cl002","w7cl008",
"w7lp001","w7lp001","w7cl008","w7cl004","w7lp001"
$table = @{}
$pcs | Group-Object -NoElement | ForEach-Object { $table[$_.Name] = $_.Count }
不需要看起来像C#和VBScript的邪恶组合的笨拙循环和代码(老实说,代码中的实际工作行没有一个看起来像PowerShell,除了前三个和最后一个)。
如果您需要数组数组而不是哈希表,您也可以这样做:
$result = $pcs | Group-Object -NoElement | ForEach-Object { ,($_.Name, $_.Count) }
但是,你真的不希望以这种方式工作。首先,您可能经常会对数组或标量作为项目感到困惑。某些操作可能会再次自动展开阵列等等。恕我直言,如果可以,可以更好地处理对象。在这种情况下,只需直接使用Group-Object
的结果即可。它具有方便的Name
和Count
属性,可以明确说明它们的内容,而不是[0]
和[1]
更加不透明。
如果您需要更好的属性名称,只需投射到新对象:
$pcs | group -n | % {
New-Object PSObject -Property @{
PC = $_.Name
Count = $_.Count
}
}
或
$pcs | group -n | select @{l='PC';e={$_.Name}},Count
通常,在使用PowerShell时,请将您的数据视为对象,将您的问题视为对这些对象的操作。然后尝试找到如何使用语言已经给你的东西来进行这些操作。操作集合类或带有大量循环的类似C的代码在PowerShell中几乎总是看起来不合适 - 通常是有充分理由的,因为管道通常是更好,更容易和更短的方法来实现相同的。我可以计算过去几年我在PowerShell中使用for
循环的次数,但我不需要双手计算我使用{{1}的次数。循环。这些都很难用。
答案 1 :(得分:0)
一般来说,在这种情况下我最终得到的不是2D数组,而是元组数组或自定义对象数组。这是import-csv默认提供的内容。对于我的工作,这是关系的一个很好的表示,我想要的许多变换是set ops和relational ops的组合。
是的,我只是Powershell的初学者。