使用PowerShell解析/格式化字符串

时间:2011-05-19 05:26:19

标签: parsing powershell powershell-v2.0

original question不是关于powershell的。我假设这些基地:

  • 我们正在运行Windows 7
  • 我们要解析Windows 7附带的systeminfo实用程序的结果
  • 我们希望从输出中提取有关网络适配器的信息,并将其放入某个数据结构中以供进一步处理。

现在,我知道有更好的方法来获取网卡信息,而不是运行systeminfo和解析输出。我的兴趣不在于这个特定的效用。我正在考虑在PowerShell中解析/格式化一些文本的通用任务。我认为powershell非常适合这类任务,可能比C#更好(取决于特定要求)。这就是为什么我在powershell中提供原始问题的my answer

我的问题是,这是。我总觉得PowerShell的一些语法有点麻烦。 您如何改进我的代码?请注意,代码不必在完全相同的结构中返回完全相同的结果。 我正在寻找可以帮助进行文本解析/处理的技巧。我已经一次又一次地看到社区在处理大量任务时的聪明才智。我已经看到了解决复杂问题的简单解决方案,直到有人告诉你如何才能解决这些问题。这就是我要问的原因。

以下是代码:

$networkCards = systeminfo | ForEach-Object {$a=0} {
    if ($_.startswith("Network Card(s)")) {$a=1} else {if ($a) {$_}}
}

$networkCards | ForEach-Object {$data=@{}} { 
    if ($_.trim().startswith("[")) {
        $c = $_.trim(); $data[$c] = @()} else {$data[$c] += $_.trim()
    } 
}

#Now we have a hash table with the keys as requested in the question 
#and the values are lists of separate strings, but those can be easily 
#concatenated if needed. Let's display it:
$data

3 个答案:

答案 0 :(得分:1)

首先,请停止使用Powershell作为常用的脚本语言。

PowerShell使用对象和解析字符串绝对不是做你想做的事情的好方法。我必须根据我的语言调整脚本以获得$ data中的内容

对我而言,这里的事情没有意义,但你构建了一个数组哈希表,我给你开发它的方法。

所以要使用你可以写的$ data:

foreach ($key in $data.keys)
{
  write-Host ("The name is {0}, the value is {1}" -f $key, $data[$key])
}

就我而言,它给出了:

The name is [02]: fe80::391a:2817:8f3e:6f2f, the value is System.Object[]
The name is [02]: Intel(R) WiFi Link 5300 AGN, the value is System.Object[]
The name is [02]: fe80::c70:cc38:cf64:eb27, the value is System.Object[]
The name is [01]: 192.168.183.1, the value is System.Object[]
The name is [01]: 192.168.0.3, the value is System.Object[]
The name is [03]: VMware Virtual Ethernet Adapter for VMnet1, the value is System.Object[]
The name is [05]: Microsoft Virtual WiFi Miniport Adapter, the value is System.Object[]
The name is [02]: fe80::5d48:c4a:5987:ee73, the value is System.Object[]
The name is [04]: VMware Virtual Ethernet Adapter for VMnet8, the value is System.Object[]
The name is [01]: 192.168.234.1, the value is System.Object[]
The name is [01]: Intel(R) 82567LM Gigabit Network Connection, the value is System.Object[]

因为$ data [$ key]是一个数组。你可以写:

foreach ($key in $data.keys)
{
  write-Host ("The name is {0}" -f $key)
  foreach($line in $data[$key])
  {
    Write-Host ("`t$line")
  }
}

对我而言,它给出了:

The name is [02]: fe80::391a:2817:8f3e:6f2f
The name is [02]: Intel(R) WiFi Link 5300 AGN
    Nom de la connexion : Connexion réseau sans fil
    État :                Support déconnecté
The name is [02]: fe80::c70:cc38:cf64:eb27
The name is [01]: 192.168.183.1
The name is [01]: 192.168.0.3
The name is [03]: VMware Virtual Ethernet Adapter for VMnet1
    Nom de la connexion : VMware Network Adapter VMnet1
    DHCP activé :         Non
    Adresse(s) IP
The name is [05]: Microsoft Virtual WiFi Miniport Adapter
    Nom de la connexion : Connexion réseau sans fil 2
    État :                Support déconnecté
The name is [02]: fe80::5d48:c4a:5987:ee73
The name is [04]: VMware Virtual Ethernet Adapter for VMnet8
    Nom de la connexion : VMware Network Adapter VMnet8
    DHCP activé :         Non
    Adresse(s) IP
The name is [01]: 192.168.234.1
The name is [01]: Intel(R) 82567LM Gigabit Network Connection
    Nom de la connexion : Connexion au réseau local
    DHCP activé :         Oui
    Serveur DHCP :        192.168.0.254
    Adresse(s) IP

答案 1 :(得分:0)

我将试着调整上面的答案:-):

虽然Powershell可用于解析来自例如的信息。 systeminfo,有更好的信息接口。看看Get-WmiObject。在这种情况下,似乎会想到Get-WmiObject Win32_NetworkAdapterWin32_NetworkAdapterConfiguration。还有Win32_NetworkProtocolWin32_NetworkConnection可以为您提供所需的信息。

Select-ObjectSort-ObjectFormat-Table结合使用,以显示您需要的数据。

答案 2 :(得分:0)

每个人都在谈论对象是正确的。我们的想法是将一个对象从一个方法直接发送到另一个方法,然后对该对象进行操作。我不是PS的大师,但我开始明白了。希望这个脚本能让你前进一点。

$text = @"
key1:value1
key2:value2
key3:value3
"@
$map = @{}
($text -split "`n") | Where-Object {$_ -imatch 'key2'} | foreach-object {$tokens = $_ -split ":"; $map.Add($tokens[0],$tokens[1])}
$map