Powershell等效于cp -n,即复制文件而不覆盖

时间:2016-03-12 08:10:38

标签: windows powershell copy-item

我经常需要在驱动器之间复制大量文件,并且该过程通常会启动和停止。在posix shell中,我可以使用<html> <style> .drag { position:absolute; z-index:0; } #A { position:absolute; z-index:0; width:20px; height:10px; } </style> <input type="text" class="drag" id="A"> <script> $('#A').on('click',function() { $(this).resizable({ ghost:true }); }); </script> </html> 来覆盖现有文件,但在powershell中cp -n似乎没有等效的“不覆盖”开关。

这意味着如果我必须停止并开始这个过程,我必须使用

copy-item

工作正常,但如果我有一百万个要复制的文件,有时会发生,我想每次都要执行ls -Recurse|%{ if (-Not(test-path($_fullname.replace("D:\", "E:\")))){ cp $_.fullname $_.fullname.replace("D:\", "E:\"); } } 会有一些开销。

编辑:BTW我试过test-path,但扫描已经存在的文件需要花费很长时间。如果我使用上面的脚本并且我已经完成了大型会话,那么在开始复制新文件之前会有几秒钟的暂停;使用robocopy,它甚至在开始复制之前花费了几分钟来运行已经复制的文件。

1 个答案:

答案 0 :(得分:2)

另一种方法是使用[System.IO.File]::Copy(source,dest),当destionation存在时会抛出异常,但是你必须处理异常处理+创建目录的开销,所以它可能没什么用处。 / p>

您可以直接使用.NET Exists()方法来减少路径测试中的一些PowerShell开销(2/3)。我没有将Exists() - 调用包装在函数中,因为它增加了PowerShell开销。

#Avoid aliases in scripts. You want people to be able to read it later
Get-ChildItem -Recurse| ForEach-Object {
    if (-Not([System.IO.File]::Exists($_fullname.replace("D:\", "E:\")) -or [System.IO.Directory]::Exists($_fullname.replace("D:\", "E:\")))){
        Copy-Item -Path $_.fullname -Destination $_.fullname.replace("D:\", "E:\")
    }
}

比较:

Measure-Command { 1..100000 | % { [System.IO.File]::Exists("C:\users\frode") -or [System.IO.Directory]::Exists("C:\users\frode") } } | Select-Object -ExpandProperty totalseconds

6,7130002

Measure-Command { 1..100000 | % { Test-Path "C:\users\frode" } } | Select-Object -ExpandProperty totalseconds

22,4492812