使用 PowerShell 筛选日志文件以创建 csv 报告
Filter logfile to create a csv report using PowerShell
我在日志文件中有一个 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)
状态:(r/w,在线,映射)
我需要的第四个细节是占用尺寸: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
$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
参数更改它。
- 要仅提取 Total Space
和 Occupied 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 输出中反映为不同的列),您必须这样创建它们,这需要相应地将输入解析为不同的值。
我在日志文件中有一个 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)
状态:(r/w,在线,映射)
我需要的第四个细节是占用尺寸: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
$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
参数更改它。
- 要仅提取 Total Space
和 Occupied 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 输出中反映为不同的列),您必须这样创建它们,这需要相应地将输入解析为不同的值。
- 一行