【问题标题】:Parsing robocopy log file to PSCustomObject将 robocopy 日志文件解析为 PSCustomObject
【发布时间】:2015-04-03 05:34:25
【问题描述】:

我正在尝试从 robocopy 日志文件创建 PSCustomObject。第一部分非常简单,但我正在努力处理$Footer 部分。我似乎找不到拆分价值观的好方法。

如果每个条目都有自己的Property,那就太好了,因此可以使用例如$Total.Dirs$Skipped.Dirs。我在考虑Import-CSV,因为它让您拥有列标题非常棒。但这似乎不适合这里。我找到了另一个解决方案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

感谢您的帮助。

【问题讨论】:

  • 我知道你在问什么,但不知道你对输出的期望。您是否有一个名为 Dirs 的属性,其中包含总计、复制等的子属性。

标签: parsing powershell text


【解决方案1】:

您可以进一步清理它,但这是我将采取的基本方法。

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() 中的另一个参数,我们指定要返回的元素数量。

$_.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

【讨论】:

  • 谢谢你,马特,你是老板!我不知道 Split 可以实现这一点 ($_.Split(':',2))。真的很棒的解决方案! :) 我现在明白它是如何完成的了。
  • 我添加的一个小改进是Total = [TimeSpan]$Array[0]
  • 如果您需要多个值,请将结果保存到一个变量中,以便您只读取日志文件一次:$robolog = ConvertFrom-RobocopyLog C:\temp\log.log ($robolog).Files.Total = 203 ($robolog).Files.FAILED = 0跨度>
【解决方案2】:

不清楚你想做什么,但这将在某种程度上向你展示如何将统计数据放入对象数组中

$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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2012-04-03
    • 2016-01-09
    相关资源
    最近更新 更多