Powershell 默认情况下,复制项将被覆盖

Powershell 默认情况下,复制项将被覆盖,powershell,Powershell,我期望从以下代码中得到的行为是: 获取源目录中的文件列表 仅当每个文件不存在时,才循环并复制到备份目标 if (!(Test-Path C:\Folder\Destination)) { New-Item -ItemType Directory -Force -Path C:\Folder\Destination } $originalfiles = Get-ChildItem -Path "C:\Folder\Source" $originalfiles foreach ($fil

我期望从以下代码中得到的行为是:

  • 获取源目录中的文件列表
  • 仅当每个文件不存在时,才循环并复制到备份目标

    if (!(Test-Path C:\Folder\Destination)) {
       New-Item -ItemType Directory -Force -Path C:\Folder\Destination
    }
    
    $originalfiles = Get-ChildItem -Path  "C:\Folder\Source"
    $originalfiles
    
    foreach ($file in $originalfiles) {
        Write-Host
        Write-Host File Name: -ForegroundColor DarkYellow
        Write-Host $file.Name
        Write-Host File Path: -ForegroundColor DarkYellow
        Write-Host $file.FullName
    
        $src = $file.FullName
        $dest = "C:\Folder\Destination\$($file.Name)"
    
        Copy-Item $src $dest
    }
    
  • 我本以为
    Copy Item
    cmdlet默认不覆盖,除非指定
    -Force
    标志。这是我在过去遇到我确实想覆盖的情况时会看到的行为

    另外,我认为这可能是引入了
    foreach
    循环,但我自己尝试了copy命令,为单个文件使用硬编码路径,但仍然是一样的

    我应该重新启动IDE,还是我忽略了这个错误

    如有疑问,请阅读

    -强制力

    允许cmdlet复制无法更改的项目,例如通过只读文件或别名进行复制

    复制项的默认行为是替换现有项。
    -Force
    开关仅用于强制替换,例如,如果目标文件设置了只读属性


    您可以使用
    -Confirm
    复制项目
    执行操作之前获得提示,也可以使用
    -WhatIf
    查看cmdlet将执行什么操作。

    将项目复制到目标,即使该项目已存在于目标中,这似乎是
    复制项目
    的预期行为。我建议进行测试,如果目标文件路径存在,则只复制尚未存在的文件

    $destinationPath = 'C:\tryout\destination';
    if (!(Test-Path $destinationPath)) 
    {
       New-Item -ItemType Directory -Force -Path $destinationPath;
    }
    
    $sourcePath = 'C:\tryout\source';
    $originalfiles = Get-ChildItem -Path $sourcePath;
    $originalfiles;
    
    foreach ($file in $originalfiles) 
    {
        Write-Host;
        Write-Host File Name: -ForegroundColor DarkYellow;
        Write-Host $file.Name;
        Write-Host File Path: -ForegroundColor DarkYellow;
        Write-Host $file.FullName;
    
        $src = $file.FullName;
        $dest = "C:\tryout\destination\$($file.Name)";
    
        if (!(Test-Path $dest))
        {
            Copy-Item $src -Destination $dest;
        }
    }
    

    旧的,但我发现了一个简短的表达:

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

    它将所有文件从
    $dir\u从
    复制到
    $dir\u到
    ,但不复制(排除部分)名称已在
    $dir\u到

    中的文件,如果您担心被覆盖,请快速执行以下操作:

    function mycopy { 
      if (! (test-path $args[1])) { copy $args[0] $args[1] } else { 'file exists' } 
    }
    

    仅当文件在目标位置不存在时才复制递归文件的版本。如果需要,它会创建子文件夹。它不会创建空文件夹。如果需要,请将
    -File
    Get ChildItem

    $srcDirPath = "C:\SourceDir"
    $destDirPath = "C:\DestinationDir"
    # Get list of files from source dir recursively. It doesn't list hidden files by default 
    # Remove where{} if you don't need to exclude files by name, in this sample I exclude all README.md in any folders
    $fileList = Get-ChildItem -Path $srcDirPath -File -Recurse | where{$_.Name -ne 'README.md'}
    # get source dir path just in case to exactly match Get-ChildItem paths
    $fullSrcDirPath = (Get-Item -Path $srcDirPath).FullName
    foreach($file in $fileList)
    {
        # build full destination file path
        $destFilePath = $destDirPath + $file.FullName.Remove(0, $fullSrcDirPath.Length)
        # proceed only if file doesn't exist in destination
        if(-not (Test-Path "$destFilePath"))
        {
            # Copy-Item can't create subfolders, so create subfolder if it doesn't exist
            # Get full destination folder path for current file
            $curDestDir = Split-Path $destFilePath -Parent
            if(-not (Test-Path "$curDestDir"))
            {
                # create subfolder(s)
                # $res here suppresses output
                $res = New-Item -Path "$curDestDir" -ItemType "directory"
            }
            Copy-Item -Path $file.FullName -Destination "$destFilePath"
        }
    }
    

    好的,我确实读了文档,以及我旁边的奥莱利食谱,但是我再次检查了文档,我不确定你到底想让我去哪里看。复制项的默认行为是否尚未保留现有文件?我还应该提到,这需要以静默方式运行,因此我不能使用确认开关。默认行为是替换现有项。
    -Force
    开关仅用于强制替换,例如,如果目标文件设置了只读属性。如文件所述。啊,好的,我现在明白了。这不是我解释文档的方式,但在解释时它是有意义的。谢谢你,这会很完美的。它确实有效,我之前测试过它,但我确信复制项可以像问题中描述的那样工作。我会把它标记为一个答案,因为它解决了我的问题,但如果其他人感到困惑,另一个答案会告诉我们Powershell。干杯如果您认为答案解决了问题,请单击绿色复选标记将其标记为“已接受”。这有助于将重点放在仍然没有答案的旧文件上。这并不说明何时有人想使用
    -recurse
    。这是唯一一个对我有效的方法,可以复制和覆盖同名的现有文件。对于不熟悉Powershell的用户,应在引号中定义$dir_from和$dir_to。例如,$dir_to=“C:\users\…”如果有人想使用
    -recurse
    ,则此选项无效。