1

我在日志文件中有一个 NetApp 日志输出,格式如下。

DeviceDetails.log 文件内容

  /vol/DBCXARCHIVE002_E_Q22014_journal/DBCXARCHIVE002_E_Q22014_journal    1.0t (1149038714880) (r/w, online, mapped)
    Comment: " "
    Serial#: e3eOF4y4SRrc
    Share: none
    Space Reservation: enabled (not honored by containing Aggregate)
    Multiprotocol Type: windows_2008
    Maps: DBCXARCHIVE003=33
    Occupied Size: 1004.0g (1077986099200)
    Creation Time: Wed Apr 30 20:14:51 IST 2014
    Cluster Shared Volume Information: 0x0 
    Read-Only: disabled
/vol/DBCXARCHIVE002_E_Q32014_journal/DBCXARCHIVE002_E_Q32014_journal  900.1g (966429273600)  (r/w, online, mapped)
    Comment: " "
    Serial#: e3eOF507DSuU
    Share: none
    Space Reservation: enabled (not honored by containing Aggregate)
    Multiprotocol Type: windows_2008
    Maps: DBCXARCHIVE003=34
    Occupied Size:  716.7g (769556951040) 
    Creation Time: Tue Aug 12 20:24:14 IST 2014
    Cluster Shared Volume Information: 0x0 
    Read-Only: disabled 

其中输出只有 2 个设备,它在日志文件中附加了超过 x 个设备。

我只需要每个模块的 4 个详细信息,第一行包含 3 个所需的详细信息

设备名称:/vol/DBCXARCHIVE002_E_Q22014_journal/DBCXARCHIVE002_E_Q22014_journal

总容量 : 1.0t (1149038714880)

状态:(读/写,在线,映射)

我需要的第四个细节是占用大小:1004.0g(1077986099200)

因此 CSV 输出应如下所示:在此处输入图像描述

我不仅仅是编码的初学者并试图用下面的代码来实现这一点,但它并没有多大帮助:/

$logfile = Get-Content .\DeviceDetails.log
$l1 = $logfile | select-string "/vol"
$l2 = $logfile | select-string "Occupied Size: " 

$objs =@()
$l1 | ForEach {
$o = $_ 
$l2 | ForEach {
    $o1 = $_
    $Object22 = New-Object PSObject -Property @{
        'LUN Name , Total Space, Status, Occupied Size'  = "$o"
        'Occupied Size'  = "$o1"           
    }           

}
$objs += $Object22  
}
$objs
4

1 回答 1

0
$obj = $null # variable to store each output object temporarily
Get-Content .\t.txt | ForEach-Object { # loop over input lines
  if ($_ -match '^\s*(/vol.+?)\s+(.+? \(.+?\))\s+(\(.+?\))') {
    # Create a custom object with all properties of interest,
    # and store it in the $obj variable created above.
    # What the regex's capture groups - (...) - captured is available in the
    # the automatic $Matches variable via indices starting at 1.
    $obj = [pscustomobject] @{
      'Device Name' = $Matches[1]
      'Total Space' = $Matches[2]
      'Status' = $Matches[3]
      'Occupied Size' = $null # filled below
    }
  } elseif ($_ -match '\bOccupied Size: (.*)') {
    # Set the 'Occupied Size' property value...
    $obj.'Occupied Size' = $Matches[1]
    # ... and output the complete object.
    $obj
  }
} | Export-Csv -NoTypeInformation out.csv

- 注意Export-Csv默认为 ASCII 输出编码;-Encoding用参数改变它。
- 要仅提取and列中的数字,请使用(...)and代替。 Total SpaceOccupied Size
$_ -match '^\s*(/vol.+?)\s+.+?\s+\((.+?)\)\s+(\(.+?\))'
$_ -match '\bOccupied Size: .+? \((.*)\)'

请注意此解决方案如何逐行处理输入文件,这会降低内存使用率,但通常会以牺牲性能为代价。


至于你尝试了什么:

  • 您将整个输入文件收集为内存中的数组 ( $logfile = Get-Content .\DeviceDetails.log)

  • 然后,您将此数组过滤两次成平行数组,其中包含相应的感兴趣的行。

  • 当您尝试嵌套处理这两个数组时会出现问题。您必须并行枚举它们,而不是嵌套,因为它们对应的索引包含匹配的条目。

  • 此外:

    • 诸如'LUN Name , Total Space, Status, Occupied Size' = "$o"创建一个名为 的单个属性的行LUN Name , Total Space, Status, Occupied Size,这不是意图。
    • 为了创建不同的属性(在 CSV 输出中反映为不同的列),您必须照此创建它们,这需要将输入相应地解析为不同的值。
于 2017-12-17T19:46:48.850 回答