将 robocopy 日志文件解析为 PSCustomObject
Parsing robocopy log file to PSCustomObject
我正在尝试从 robocopy 日志文件创建 PSCustomObject
。第一部分非常简单,但我在 $Footer
部分苦苦挣扎。我似乎找不到拆分值的好方法。
如果每个条目都有自己的 Property
就好了,所以可以使用例如 $Total.Dirs
或 $Skipped.Dirs
。我在考虑 Import-CSV
,因为它非常适合让您拥有列 headers。但这似乎不适合这里。我找到了另一个解决方案 here,但它似乎有点矫枉过正。
代码:
Function ConvertFrom-RobocopyLog {
Param (
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
[String]$LogFile
)
Process {
$Header = Get-Content $LogFile | select -First 10
$Footer = Get-Content $LogFile | select -Last 7
$Header | ForEach-Object {
if ($_ -like "*Source*") {$Source = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Dest*") {$Destination = (($_.Split(':'))[1]).trim()}
}
$Footer | ForEach-Object {
if ($_ -like "*Dirs*") {$Dirs = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Files*") {$Files = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Times*") {$Times = (($_.Split(':'))[1]).trim()}
}
$Obj = [PSCustomObject]@{
'Source' = $Source
'Destination' = $Destination
'Dirs' = $Dirs
'Files' = $Files
'Times' = $Times
}
Write-Output $Obj
}
}
日志文件:
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : Wed Apr 01 14:28:11 2015
Source : \SHARE\Source\
Dest : \SHARE\Target\
Files : *.*
Options : *.* /S /E /COPY:DAT /PURGE /MIR /Z /NP /R:3 /W:3
------------------------------------------------------------------------------
0 Files...
0 More Folders and files...
------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras
Dirs : 2 0 2 0 0 0
Files : 203 0 203 0 0 0
Bytes : 0 0 0 0 0 0
Times : 0:00:00 0:00:00 0:00:00 0:00:00
Ended : Wed Apr 01 14:28:12 2015
感谢您的帮助。
您可以进一步清理它,但这是我会采用的基本方法。
Function ConvertFrom-RobocopyLog {
Param (
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
[String]$LogFile
)
Process {
$Header = Get-Content $LogFile | select -First 10
$Footer = Get-Content $LogFile | select -Last 7
$Header | ForEach-Object {
if ($_ -like "*Source*") {$Source = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Dest*") {$Destination = (($_.Split(':'))[1]).trim()}
}
$Footer | ForEach-Object {
if ($_ -like "*Dirs*"){
$lineAsArray = (($_.Split(':')[1]).trim()) -split '\s+'
$Dirs = [pscustomobject][ordered]@{
Total = $lineAsArray[0]
Copied = $lineAsArray[1]
Skipped = $lineAsArray[2]
Mismatch = $lineAsArray[3]
FAILED = $lineAsArray[4]
Extras = $lineAsArray[5]
}
}
if ($_ -like "*Files*"){
$lineAsArray = ($_.Split(':')[1]).trim() -split '\s+'
$Files = [pscustomobject][ordered]@{
Total = $lineAsArray[0]
Copied = $lineAsArray[1]
Skipped = $lineAsArray[2]
Mismatch = $lineAsArray[3]
FAILED = $lineAsArray[4]
Extras = $lineAsArray[5]
}
}
if ($_ -like "*Times*"){
$lineAsArray = ($_.Split(':',2)[1]).trim() -split '\s+'
$Times = [pscustomobject][ordered]@{
Total = $lineAsArray[0]
Copied = $lineAsArray[1]
FAILED = $lineAsArray[2]
Extras = $lineAsArray[3]
}
}
}
$Obj = [PSCustomObject]@{
'Source' = $Source
'Destination' = $Destination
'Dirs' = $Dirs
'Files' = $Files
'Times' = $Times
}
Write-Output $Obj
}
}
我想创建一个函数来解析页脚行,但 $Times
是一个特例,因为它没有所有相同的数据列。
与 $Times
的 重要 区别在于我们进行拆分的方式。由于该字符串包含多个冒号,因此我们需要考虑到这一点。使用 .Split()
中的另一个参数,我们将元素数指定为 return。
$_.Split(':',<i><b>2</b></i>)[1]
因为这些日志总是有输出并且没有空白行元素,我们可以假设 $lineAsArray
的解析元素总是有 6 个元素。
示例输出
Source : \SHARE\Source\
Destination : \SHARE\Target\
Dirs : @{Total=2; Copied=0; Skipped=2; Mismatch=0; FAILED=0; Extras=0}
Files : @{Total=203; Copied=0; Skipped=203; Mismatch=0; FAILED=0; Extras=0}
Times : @{Total=0:00:00; Copied=0:00:00; FAILED=0:00:00; Extras=0:00:00}
因此,如果您想要复制的总文件数,您现在可以使用点表示法。
(ConvertFrom-RobocopyLog C:\temp\log.log).Files.Total
203
不太清楚您想做什么,但这将在某种程度上向您展示如何将统计数据放入对象数组中
$statsOut = @()
$stats = Get-Content $LogFile | select -Last 6 | select -first 4
$stats | % {
$s = $_ -split "\s+"
$o = new-object -type pscustomobject -property @{"Name"=$s[0];"Total"=$s[2];"Copied"=$s[3];"Skipped"=$s[4];"mismatch"=$s[5]};
$statsOut += ,$o
}
给出:
[PS] > $statsOut | ft -Auto
mismatch Name Skipped Total Copied
-------- ---- ------- ----- ------
0 Dirs 2 2 0
0 Files 203 203 0
0 Bytes 0 0 0
我正在尝试从 robocopy 日志文件创建 PSCustomObject
。第一部分非常简单,但我在 $Footer
部分苦苦挣扎。我似乎找不到拆分值的好方法。
如果每个条目都有自己的 Property
就好了,所以可以使用例如 $Total.Dirs
或 $Skipped.Dirs
。我在考虑 Import-CSV
,因为它非常适合让您拥有列 headers。但这似乎不适合这里。我找到了另一个解决方案 here,但它似乎有点矫枉过正。
代码:
Function ConvertFrom-RobocopyLog {
Param (
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
[String]$LogFile
)
Process {
$Header = Get-Content $LogFile | select -First 10
$Footer = Get-Content $LogFile | select -Last 7
$Header | ForEach-Object {
if ($_ -like "*Source*") {$Source = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Dest*") {$Destination = (($_.Split(':'))[1]).trim()}
}
$Footer | ForEach-Object {
if ($_ -like "*Dirs*") {$Dirs = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Files*") {$Files = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Times*") {$Times = (($_.Split(':'))[1]).trim()}
}
$Obj = [PSCustomObject]@{
'Source' = $Source
'Destination' = $Destination
'Dirs' = $Dirs
'Files' = $Files
'Times' = $Times
}
Write-Output $Obj
}
}
日志文件:
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : Wed Apr 01 14:28:11 2015
Source : \SHARE\Source\
Dest : \SHARE\Target\
Files : *.*
Options : *.* /S /E /COPY:DAT /PURGE /MIR /Z /NP /R:3 /W:3
------------------------------------------------------------------------------
0 Files...
0 More Folders and files...
------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras
Dirs : 2 0 2 0 0 0
Files : 203 0 203 0 0 0
Bytes : 0 0 0 0 0 0
Times : 0:00:00 0:00:00 0:00:00 0:00:00
Ended : Wed Apr 01 14:28:12 2015
感谢您的帮助。
您可以进一步清理它,但这是我会采用的基本方法。
Function ConvertFrom-RobocopyLog {
Param (
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
[String]$LogFile
)
Process {
$Header = Get-Content $LogFile | select -First 10
$Footer = Get-Content $LogFile | select -Last 7
$Header | ForEach-Object {
if ($_ -like "*Source*") {$Source = (($_.Split(':'))[1]).trim()}
if ($_ -like "*Dest*") {$Destination = (($_.Split(':'))[1]).trim()}
}
$Footer | ForEach-Object {
if ($_ -like "*Dirs*"){
$lineAsArray = (($_.Split(':')[1]).trim()) -split '\s+'
$Dirs = [pscustomobject][ordered]@{
Total = $lineAsArray[0]
Copied = $lineAsArray[1]
Skipped = $lineAsArray[2]
Mismatch = $lineAsArray[3]
FAILED = $lineAsArray[4]
Extras = $lineAsArray[5]
}
}
if ($_ -like "*Files*"){
$lineAsArray = ($_.Split(':')[1]).trim() -split '\s+'
$Files = [pscustomobject][ordered]@{
Total = $lineAsArray[0]
Copied = $lineAsArray[1]
Skipped = $lineAsArray[2]
Mismatch = $lineAsArray[3]
FAILED = $lineAsArray[4]
Extras = $lineAsArray[5]
}
}
if ($_ -like "*Times*"){
$lineAsArray = ($_.Split(':',2)[1]).trim() -split '\s+'
$Times = [pscustomobject][ordered]@{
Total = $lineAsArray[0]
Copied = $lineAsArray[1]
FAILED = $lineAsArray[2]
Extras = $lineAsArray[3]
}
}
}
$Obj = [PSCustomObject]@{
'Source' = $Source
'Destination' = $Destination
'Dirs' = $Dirs
'Files' = $Files
'Times' = $Times
}
Write-Output $Obj
}
}
我想创建一个函数来解析页脚行,但 $Times
是一个特例,因为它没有所有相同的数据列。
与 $Times
的 重要 区别在于我们进行拆分的方式。由于该字符串包含多个冒号,因此我们需要考虑到这一点。使用 .Split()
中的另一个参数,我们将元素数指定为 return。
$_.Split(':',<i><b>2</b></i>)[1]
因为这些日志总是有输出并且没有空白行元素,我们可以假设 $lineAsArray
的解析元素总是有 6 个元素。
示例输出
Source : \SHARE\Source\
Destination : \SHARE\Target\
Dirs : @{Total=2; Copied=0; Skipped=2; Mismatch=0; FAILED=0; Extras=0}
Files : @{Total=203; Copied=0; Skipped=203; Mismatch=0; FAILED=0; Extras=0}
Times : @{Total=0:00:00; Copied=0:00:00; FAILED=0:00:00; Extras=0:00:00}
因此,如果您想要复制的总文件数,您现在可以使用点表示法。
(ConvertFrom-RobocopyLog C:\temp\log.log).Files.Total
203
不太清楚您想做什么,但这将在某种程度上向您展示如何将统计数据放入对象数组中
$statsOut = @()
$stats = Get-Content $LogFile | select -Last 6 | select -first 4
$stats | % {
$s = $_ -split "\s+"
$o = new-object -type pscustomobject -property @{"Name"=$s[0];"Total"=$s[2];"Copied"=$s[3];"Skipped"=$s[4];"mismatch"=$s[5]};
$statsOut += ,$o
}
给出:
[PS] > $statsOut | ft -Auto
mismatch Name Skipped Total Copied
-------- ---- ------- ----- ------
0 Dirs 2 2 0
0 Files 203 203 0
0 Bytes 0 0 0