【问题标题】:Robocopy and get Copied file nameRobocopy 并获取复制的文件名
【发布时间】:2015-04-10 00:37:17
【问题描述】:

我正在使用 robocopy 仅同步较新的文件,但我还需要获取正在复制的文件名。

我必须进一步使用复制的文件名在其他文件中创建条目。

我找不到开关,它只显示复制的文件名,任何批处理文件的powershell脚本也可以。

【问题讨论】:

    标签: powershell batch-file robocopy


    【解决方案1】:

    user182904,

    我已根据您的要求修改了答案。

    试试下面的 cmd 文件。

    1) 它将从 robocopy 创建一个日志文件,其中仅复制文件夹\文件。

    2) 然后它会将该日志文件剥离为仅复制的文件。

    @echo off
    
    rem source folders for robocopy
    set source="c:\test\files"
    set destin="c:\test\files2"
    
    rem logfile names
    set sourcelogfile=log-from-robocopy.txt
    set destinlogfile=log-just-files.txt
    
    rem robocopy command to output files copied
    robocopy %source%  %destin% /e  /LOG:"%sourcelogfile%" /NP /NS /NC /NDL /TEE /NJH /NJS
    
    rem for loop through robocopy output and stip it down to just file names into new logfile
    for /f "tokens=*" %%i in (%sourcelogfile%) do (
        for /f "delims=" %%f in ("%%i") do (
            echo %%~nxf >> %destinlogfile%
        )
    )
    
    rem end of code
    

    您可以将选项添加到 Robocopy 行,但您需要在该行末尾添加选项,以输出脚本其余部分将解析的日志文件。

    希望对您有所帮助。

    可以在此处找到所有 robocopy 开关的详细信息:

    来源:http://ss64.com/nt/robocopy.html

    【讨论】:

    • 感谢您的回复。 Robocopy 产生大量输出,我只想要被复制文件的名称或解析该日志文件并仅生成正在复制的“文件”的脚本。
    【解决方案2】:

    此函数解析所有 RoboCopy 文本输出并将其输出为一个不错的对象。

    像这样使用它:

    $RoboCopyOutput = robocopy $source $destination /ROBOSWITCHES
    
    Parse-RoboCopyOutput $RoboCopyOutput
    

    或者这个:

    Parse-RoboCopyOutput (robocopy e t /s)
    

    (显示错误处理)

    我不能声称所有的忍者正则表达式技能都是我自己的:几年前我在网上找到了一些东西,并随着时间的推移对其进行了扩展。抱歉,我现在找不到原始文章,或者我会发布指向该文章的链接。

    我的 RoboCopy 版本检查仅查找我在我的环境中遇到的版本,并不详尽,因此请注意这一点。找出您的版本的日期格式并将其添加到 switch 语句中应该很容易。

        Function Parse-RoboCopyOutput ($RoboCopyOutput)
    {
        #Get RoboCopy version info to determine the date format
        switch ((Get-Command robocopy).FileVersionInfo.ProductVersion)
        {
            {$_ -eq 'XP027'}            {$RobocopyDateFormat = 'ddd MMM dd HH:mm:ss yyyy' ; break}  #Vista / Windows 7 / Server 2008
            {$_ -eq '6.2.9200.16384'}   {$RobocopyDateFormat = 'dd MMMM yyyy HH:mm:ss' ; break}     #Windows 8
            {$_ -eq '6.3.9600.16384'}   {$RobocopyDateFormat = 'dd MMMM yyyy HH:mm:ss' ; break}     #Windows 8.1
            default                     {throw "Unknown robocopy version."}
        }
    
        #Find the line numbers of the '----' spacers in the robocopy output
        $null,$HeaderStart,$HeaderEnd,$FooterStart = $RoboCopyOutput | Select-String  "----" | Foreach-Object {$_.linenumber}
    
        #Create the object to store all the parsed robocopy output information
        $RoboObject = New-Object PSObject
    
        #Grab the first section of the robocopy output by line number
        $RoboCopyOutput[$HeaderStart..$HeaderEnd] | Foreach-Object `
        {
            Switch -regex ($_)
            {
                'Started :(.*)'     {
                                        Add-Member -InputObject $RoboObject -Name StartTime -Value `
                                            ([datetime]::ParseExact($matches[1].trim(),$RobocopyDateFormat,$null)) -MemberType NoteProperty
                                    }
                'Source :(.*)'      {
                                        Add-Member -InputObject $RoboObject -Name Source -Value ($matches[1].trim()) -MemberType NoteProperty
                                    }
                'Dest (.)(.*)'      {
                                        Add-Member -InputObject $RoboObject -Name Destination -Value ($matches[2].trim()) -MemberType NoteProperty
                                    }
                '^    Files :(.*)'  {
                                        Add-Member -InputObject $RoboObject -Name FilesToCopy -Value ($matches[1].trim()) -MemberType NoteProperty
                                    }
                'Exc Files :(.*)'   {
                                        Add-Member -InputObject $RoboObject -Name ExcFiles -Value ($matches[1].trim()) -MemberType NoteProperty
                                    }
                'Exc Dirs :(.*)'    {
                                        Add-Member -InputObject $RoboObject -Name ExcDirs -Value ($matches[1].trim()) -MemberType NoteProperty
                                    }
                'Options :(.*)'     {
                                        Add-Member -InputObject $RoboObject -Name Options -Value ($matches[1].trim()) -MemberType NoteProperty
                                    }
            }
        }
    
        #Grab the second section of the robocopy output by line number (if the copy has completed).
        if ($FooterStart)
        {
            $RoboCopyOutput[$FooterStart..($RoboCopyOutput.Count -1)] | Foreach-Object `
            {
                Switch -regex ($_)
                {
                    'Ended :(.*)'       {
                                            Add-Member -InputObject $RoboObject -Name StopTime `
                                                -Value ([datetime]::ParseExact($matches[1].trim(),$RobocopyDateFormat,$null)) -MemberType NoteProperty
                                        }
                    'Speed :(.*) Bytes' {
                                            Add-Member -InputObject $RoboObject -Name BytesPerSecond -Value ($matches[1].trim()) -MemberType NoteProperty
                                        }
                    '(Total.*)'         {
                                            $Columns = $_.Split() | Where-Object {$_}
                                        }
                    'Dirs :(.*)'        {
                                            $Fields = $matches[1].Split() | Where-Object {$_}
    
                                            $Dirs = New-Object PSObject
    
                                            0..5 | Foreach-Object `
                                            {
                                                Add-Member -InputObject $Dirs -Name $Columns[$_] -Value $Fields[$_] -MemberType NoteProperty
    
                                                Add-Member -InputObject $Dirs -Name 'toString' -MemberType ScriptMethod `
                                                    -Value {[string]::Join(" ",($this.psobject.Properties | Foreach-Object {"$($_.name):$($_.value)"}))} -force
                                            }
    
                                            Add-Member -InputObject $RoboObject -Name Directories -Value $Dirs -MemberType NoteProperty
                                        }
                    'Files :(.*)'       {
                                            $Fields = $matches[1].Split() | Where-Object {$_}
    
                                            $Files = New-Object PSObject
    
                                            0..5 | Foreach-Object `
                                            {
                                                Add-Member -InputObject $Files -Name $Columns[$_] -Value $Fields[$_] -MemberType NoteProperty
    
                                                Add-Member -InputObject $Files -Name 'toString' -MemberType ScriptMethod `
                                                    -Value {[string]::Join(" ",($this.psobject.Properties | Foreach-Object {"$($_.name):$($_.value)"}))} -force
                                            }
    
                                            Add-Member -InputObject $RoboObject -Name Files -Value $files -MemberType NoteProperty
                                        }
                    'Bytes :(.*)'       {
                                            $Fields = $matches[1].Split() | Where-Object {$_}
    
                                            $Fields = $Fields | Foreach-Object {$New=@();$i=0}{if ($_ -match '\d') {$New += $_;$i++} else {$New[$i-1] = ([double]$New[$i-1]) * "1${_}B"}}{$New}
    
                                            $Bytes = New-Object PSObject
    
                                            0..5 | Foreach-Object `
                                            {
                                                Add-Member -InputObject $Bytes -Name $Columns[$_] -Value $Fields[$_] -MemberType NoteProperty
    
                                                Add-Member -InputObject $Bytes -Name 'toString' -MemberType ScriptMethod `
                                                    -Value {
                                                        [string]::Join(" ",($this.psobject.Properties | Foreach-Object {"$($_.name):$($_.value)"}))
                                                        } -force
                                            }
    
                                            Add-Member -InputObject $RoboObject -Name Bytes -Value $bytes -MemberType NoteProperty
                                        }
                    }
                }
    
            #If the copy completed, calculate elapsed time
            if ($RoboObject.StopTime)
            {
                $ElapsedTime = ($RoboObject.StopTime) - ($RoboObject.StartTime)
    
                Add-Member -InputObject $RoboObject -Name ElapsedTime -Value $ElapsedTime -MemberType NoteProperty
            }
        }
        else
        {
            #Grab the RoboCopy error
            $RoboCopyOutput[($HeaderEnd +1)..($RoboCopyOutput.Count -1)] | ForEach-Object `
            {           
                $ErrorMessage += $_.ToString()          
            }
    
            Add-Member -InputObject $RoboObject -Name ErrorMessage -Value $ErrorMessage -MemberType NoteProperty
        }
    
        #Output
        $RoboObject
    }
    

    【讨论】:

    • 对不起,我刚刚意识到你在寻找一个文件列表。我很抱歉。我将保留它,因为人们可能会在输出解析器之后找到它。
    • 实际上,将文件列表属性添加到输出对象应该很容易。我会试试看的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多