2014-01-07 60 views
4

是否可以格式化Powershell中的哈希表输出以将所有值输出到一行上?在Powershell中将哈希表的输出格式化为输出到一行

例如

我有哈希表$ hashErr与以下值:

$hashErr = @{"server1" = "192.168.17.21"; 
       "server2" = "192.168.17.22"; 
       "server3" = "192.168.17.23"} 

哪些是写入日志与下面:

$hashErr.GetEnumerator() | Sort-Object Name | ForEach-Object {ForEach-Object {"{0}`t{1}" -f $_.Name,($_.Value -join ", ")} | Add-Content $log 

的将导致以下被写入到日志:

Name       Value 
    ----       ----- 
server2      192.168.17.22 
server1      192.168.17.21 
server3      192.168.17.23 

我的问题是,怎么可以我格式化这个哈希表,所以输出全部写入一行,如下所示?

server2 192.168.17.22 | server1 192.168.17.21 | server3 192.168.17.23 

这可以通过循环哈希表中的所有值并将它们放入数组中,但肯定存在更直接的方法?

+0

你似乎要么有一个额外的'ForEach-Object {'或缺少'}'(要么改变代码的工作方式,但不需要外部的ForEach对象)。 – Duncan

+0

@Duncan对于这个问题,我根本没有看到需要** Foreach-Object **循环。 '$ hashErr.GetEnumerator()|排序名称“本身在他的列表中产生输出。事实上,使用** Foreach-Object **循环/格式化的字符串来完成它甚至不会写列标题。 user_invalid,这些标题来自哪里?您是否事先手动将它们添加到日志中? –

+0

标题不是手动添加的,它们似乎是哈希表的标准输出,按照项目的添加顺序,例如, 'PS M:\> $ hashErr' –

回答

8

您可以迭代散列表的键,然后在循环中查找值。通过使用管道,你并不需要一个中间收集:

($hashErr.Keys | foreach { "$_ $($hashErr[$_])" }) -join "|" 
1

你想保持排序,并且支持多个IP地址的单个服务器上,这两者都是在你表现而不是代码在你的输出?

如果是这样,我认为你会得到最好的仅仅是对原有稍作修改:

C:\scripts> ($hashErr.GetEnumerator() | sort Name | % { "$($_.Name) $($_.Value -join ',')" }) -join "|" 
server1 192.168.17.21|server2 192.168.17.22|server3 192.168.17.23,1.2.3.4 
+0

顺序并不重要,但我希望有可能为每个键有多个值。在任何情况下,这都很完美,正是我所期待的。谢谢您的帮助。 –

3

的V4版本理查德的解决方案:

$hashErr = @{"server1" = "192.168.17.21"; 
       "server2" = "192.168.17.22"; 
       "server3" = "192.168.17.23"} 

$hashErr.Keys.ForEach({"$_ $($hashErr.$_)"}) -join ' | ' 

server3 192.168.17.23 | server2 192.168.17.22 | server1 192.168.17.21 
1

有点迟到了,扩大对@ mjolinor的解决方案,你可以使用类型加速器[订购]:

$hashErr = [ordered]@{"server1" = "192.168.17.21"; 
      "server2" = "192.168.17.22"; 
      "server3" = "192.168.17.23"} 

$hashErr.Keys.ForEach({"$_ $($hashErr.$_)"}) -join ' | ' 

server1 192.168.17.21 | server2 192.168.17.22 | server3 192.168.17.23 

我认为[或dered]在PS v 3.0中引入。