如何不覆盖现有文件

如何不覆盖现有文件

目前,我正在使用复制项目想知道是否有一个简单的命令,可以只复制不存在的文件或按日期/时间复制的新文件。在网上查了一下,但我看到的所有内容似乎都在使用-如果什么命令。此外,还看到递归正在使用。我也不完全明白这个命令的作用。有什么想法吗?

$From = "E:\Folder\*"
$To = "\\Server\Folder"
Copy-Item -Path $From -Destination $To -Verbose

答案1

再次强调,您所追求的目标很容易通过 实现RoboCopy.exe,并且这个问题已经在这里和许多其他问答网站上被问过多次,甚至在 SU 上也是如此。

Robocopy 仅复制新文件夹和文件

以及 SO

https://stackoverflow.com/questions/23303532/use-robocopy-to-copy-only-changed-files

RC will only copy newer files. Files of the same age will be skipped.
C:\SourceFolder D:\DestinationFolder ABC.dll /XO

robocopy c:\users\valery\documents j:\robocopy /XO /E /MAXAGE:20131030 /XD
# Result: A full folders tree is created. Only new files copied.

因此,您的问题实际上与上述问题重复。

否则,您最终必须了解并执行类似下面的操作(如果您是新手,正如您所说,在一次搜索或一组搜索中很难找到):

Clear-Host
$Source      = 'D:\Temp\Source'
$Destination = 'D:\Temp\Destination'

Get-ChildItem -Path $Source -Recurse | 
ForEach-Object {
    If (Test-Path -Path "$Destination\$($PSItem.Name)")
    {
        Write-Warning -Message "`n$($PSItem.Name) already exists in $Destination. Checking timestamp`n"

        Try
        {
            "Copying file if $($PSItem.Name) is newer"
            Get-ChildItem -Path $Destination -Filter $PSItem.Name | 
            Where-Object LastWriteTime -lt $PSItem.LastWriteTime -ErrorAction Stop
            Copy-Item -Path $PSItem.FullName -Destination $Destination -Verbose -WhatIf

        }
        Catch {$PSItem.Exception.Message}
    }
    Else
    {
        Write-Host "`n$PSItem.Name does not Exist in $Destination`n" -ForegroundColor Cyan
        Copy-Item -Path $PSItem.FullName -Destination $Destination -Verbose -WhatIf
    }
}
# Results
<#
...
WARNING: 
abc.txt already exists in D:\Temp\Destination. Checking timestamp
... 

WARNING: 
LexPointOh.txt already exists in D:\Temp\Destination. Checking timestamp
Copying file if $($PSItem.Name) is newer


-a----         10-Apr-21     00:00              0 LexPointOh.txt
What if: Performing the operation 
"Copy File" on target "Item: D:\Temp\Source\LexPointOh.txt 
Destination: D:\Temp\Destination\LexPointOh.txt".

mytest - Copy.txt.Name does not Exist in D:\Temp\Destination

What if: Performing the operation "Copy File" on target 
"Item: D:\Temp\Source\mytest - Copy.txt 
Destination: D:\Temp\Destination\mytest - Copy.txt".
...
#>

只需删除-WhatIf它就可以了。

因此,根据您的陈述:

我也不完全明白这个命令的作用。

既然如此,那么我上面展示的内容将更具挑战性。这就是为什么我在原帖中向你指出了帮助文件(培训网站、Youtube 等)。

以上只是其中一种方法。PowerShell 提供了各种方法来执行 X 或 Y 操作。例如,这是执行相同用例的另一种方法。

Clear-Host

$Source      = ($SourceFiles      = Get-ChildItem -Path 'D:\Temp\Source')[0].DirectoryName
$Destination = ($DestinationFiles = Get-ChildItem -Path 'D:\Temp\Destination')[0].DirectoryName

Compare-Object -ReferenceObject $SourceFiles -DifferenceObject $DestinationFiles -IncludeEqual | 
ForEach-Object {
    If ($PSItem.SideIndicator -match '==|=>')
    {
        If (
            Get-ChildItem -Path $Destination -Filter $($PSItem.InputObject.Name) | 
            Where-Object LastWriteTime -LT  $PSItem.InputObject.LastWriteTime
        )       
        {
            Write-Warning -Message "`n$($PSItem.InputObject) already exists in $Destination. Checking timestamp`n"   
            Copy-Item -Path $PSItem.InputObject.FullName -Destination $Destination -ErrorAction SilentlyContinue -Verbose -WhatIf
        }
    }
    Else
    {
        Write-Host "`n$($PSItem.InputObject ) does not Exist in $Destination`n" -ForegroundColor Cyan
        Copy-Item -Path $PSItem.InputObject.FullName  -Destination $Destination -Verbose -WhatIf
    }
}
# Results
<#
WARNING: 
abc.txt already exists in D:\Temp\Destination. Checking timestamp

What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\abc.txt Destination: D:\Temp\Destination\abc.txt".
WARNING: 
LexPointOh.txt already exists in D:\Temp\Destination. Checking timestamp

What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\LexPointOh.txt Destination: D:\Temp\Destination\LexPointOh.txt".

mytest - Copy.txt does not Exist in D:\Temp\Destination

What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\mytest - Copy.txt Destination: D:\Temp\Destination\mytest - Copy.txt".

...
#>

然而,在大多数情况下,任何时候使用比较逻辑时,您都不会查看简单的命令。

因此,请使用正确的工具来完成工作。除非这是家庭作业,否则不要增加您的核心工作量/不要重新发明轮子。

答案2

您可以使用 cmdlet Get-ChildItem。您的脚本基本上应该具有以下流程:

  1. 检查目标文件夹中是否存在该文件
  2. 如果存在则跳过
  3. 如果不存在则复制

我在我的电脑上进行了一个非常粗略和简单的测试,这应该可行(记得根据你的用例进行修改)

$FROM = "T:\Files\Scripts1\BackItUp.ps1"
$TO = "T:\Files2"

if (Get-ChildItem -Path $TO "BackItUp.ps1") {
    Write-Host "file already exists..skipping"
} else {
    Copy-Item $FROM -Destination $TO
}

答案3

来自 Stack Overflow:

Copy-Item (Join-Path $dir_from "*") $dir_to -Exclude (Get-ChildItem $dir_to)

关联:为什么Copy-Item默认覆盖目标文件?

相关内容