我期望从以下代码中获得的行为是:
循环并将每个文件复制到备份目标,只有它尚不存在。
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
标志,否则我认为-Force
cmdlet默认为不覆盖。这是我以前在遇到我想要覆盖的情况时会看到的行为。
另外,我认为它可能是foreach
循环的引入,但我尝试了自己的复制命令,使用单个文件的硬编码路径,它仍然是相同的。
我应该重启我的IDE还是我忽略了一个错误?
答案 0 :(得分:5)
如有疑问,请阅读documentation。
<强> -Force 强>
允许cmdlet复制无法以其他方式更改的项目,例如复制只读文件或别名。
Copy-Item
的默认行为是替换现有项目。如果例如目标文件具有readonly属性集,则-Force
开关仅用于强制替换。
您可以使用-Confirm
在Copy-Item
执行操作之前收到提示,或者您可以使用-WhatIf
查看cmdlet的用途。
答案 1 :(得分:5)
似乎是Copy-Item
将项目复制到目标的预期行为,即使它已存在于目标中。我建议测试一下目标文件路径是否存在,如果文件尚不存在则只复制该文件。
$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;
}
}
答案 2 :(得分:4)
旧的,但是我发现有一个简短的表达式可以做到这一点:
Copy-Item (Join-Path $dir_from "*") $dir_to -Exclude (Get-ChildItem $dir_to)
它将所有文件从$dir_from
复制到$dir_to
,但不(-Exclude部分)复制名称已经在$dir_to
中的文件
答案 3 :(得分:1)
仅当目标位置中不存在文件时才复制文件递归的版本。如果需要,它将创建子文件夹。它不会创建空文件夹。如果需要它们,请从-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"
}
}
答案 4 :(得分:0)
如果您担心被覆盖会很快发生:
function mycopy {
if (! (test-path $args[1])) { copy $args[0] $args[1] } else { 'file exists' }
}