$from = "\\something\1 XLS\2010_04_22\*"
$to = "c:\out\1 XLS\2010_04_22\"
copy-item $from $to -Recurse
如果c:\ out \ 1 XLS \ 2010_04_22 \确实存在,则此方法有效。如果它不存在,是否可以使用单个命令创建“c:\ out \ 1 XLS \ 2010_04_22 \”。
答案 0 :(得分:94)
在PowerShell 2.0中,仍然无法使用Copy-Item cmdlet创建目标文件夹,您需要这样的代码:
$destinationFolder = "C:\My Stuff\Subdir"
if (!(Test-Path -path $destinationFolder)) {New-Item $destinationFolder -Type Directory}
Copy-Item "\\server1\Upgrade.exe" -Destination $destinationFolder
如果在Copy-Item中使用-Recurse,它将在目标中创建源结构的所有子文件夹,但即使使用-Force也不会创建实际的目标文件夹。
答案 1 :(得分:72)
是的,添加-Force
参数。
copy-item $from $to -Recurse -Force
答案 2 :(得分:10)
在PowerShell 3及更高版本中,我使用带有New-Item的Copy-Item。
<%=f.text_field 'first_name',:tabindex=>1%>
我没有在第2版中尝试过。
答案 3 :(得分:3)
$filelist | % {
$file = $_
mkdir -force (Split-Path $dest) | Out-Null
cp $file $dest
}
答案 4 :(得分:3)
function Copy-File ([System.String] $sourceFile, [System.String] $destinationFile, [Switch] $overWrite) {
if ($sourceFile -notlike "filesystem::*") {
$sourceFile = "filesystem::$sourceFile"
}
if ($destinationFile -notlike "filesystem::*") {
$destinationFile = "filesystem::$destinationFile"
}
$destinationFolder = $destinationFile.Replace($destinationFile.Split("\")[-1],"")
if (!(Test-Path -path $destinationFolder)) {
New-Item $destinationFolder -Type Directory
}
try {
Copy-Item -Path $sourceFile -Destination $destinationFile -Recurse -Force
Return $true
} catch [System.IO.IOException] {
# If overwrite enabled, then delete the item from the destination, and try again:
if ($overWrite) {
try {
Remove-Item -Path $destinationFile -Recurse -Force
Copy-Item -Path $sourceFile -Destination $destinationFile -Recurse -Force
Return $true
} catch {
Write-Error -Message "[Copy-File] Overwrite error occurred!`n$_" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
} else {
Write-Error -Message "[Copy-File] File already exists!" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
} catch {
Write-Error -Message "[Copy-File] File move failed!`n$_" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
}
答案 5 :(得分:2)
我最喜欢的是使用.Net [IO.DirectoryInfo]类,它负责一些逻辑。我实际上使用它来解决许多类似的脚本问题。它有一个.Create()方法,可以创建不存在的目录,如果存在则没有错误。
由于这仍然是一个两步问题,我使用foreach别名来保持简单。对于单个文件:
[IO.DirectoryInfo]$to |% {$_.create(); cp $from $_}
就你的多文件/目录匹配而言,我会使用RoboCopy而不是xcopy。删除&#34; *&#34;来自你的,只是使用:
RoboCopy.exe $from $to *
您仍然可以添加/ r(Recurse),/ e(Recurse包括Empty),还有50个其他有用的开关。
编辑:回顾一下这一点很简洁,但如果你不经常使用代码,那就不太可读了。通常我将它分成两部分,如下所示:
([IO.DirectoryInfo]$to).Create()
cp $from $to
此外, DirectoryInfo 是 FileInfo 的Parent属性的类型,因此如果 $ to 是文件,则可以使用它们一起:
([IO.FileInfo]$to).Parent.Create()
cp $from $to
答案 6 :(得分:2)
这是一个对我有用的例子。我有一个文本文件中的大约500个特定文件的列表,包含在大约100个不同的文件夹中,应该将其复制到备份位置,以防以后需要这些文件。文本文件包含完整的路径和文件名,每行一个。就我而言,我想从每个文件名中删除驱动器号和第一个子文件夹名称。我想将所有这些文件复制到我指定的另一个根目标文件夹下的类似文件夹结构中。希望其他用户对此有所帮助。
# Copy list of files (full path + file name) in a txt file to a new destination, creating folder structure for each file before copy
$rootDestFolder = "F:\DestinationFolderName"
$sourceFiles = Get-Content C:\temp\filelist.txt
foreach($sourceFile in $sourceFiles){
$filesplit = $sourceFile.split("\")
$splitcount = $filesplit.count
# This example strips the drive letter & first folder ( ex: E:\Subfolder\ ) but appends the rest of the path to the rootDestFolder
$destFile = $rootDestFolder + "\" + $($($sourceFile.split("\")[2..$splitcount]) -join "\")
# Output List of source and dest
Write-Host ""
Write-Host "===$sourceFile===" -ForegroundColor Green
Write-Host "+++$destFile+++"
# Create path and file, if they do not already exist
$destPath = Split-Path $destFile
If(!(Test-Path $destPath)) { New-Item $destPath -Type Directory }
If(!(Test-Path $destFile)) { Copy-Item $sourceFile $destFile }
}
答案 7 :(得分:1)
我在这里跌跌撞撞两次,这最后一次是一个独特的情况,即使我放弃使用copy-item
我想发布我使用的解决方案。
除了具有完整路径的文件之外,只有一个列表,在大多数情况下,文件没有扩展名。 -Recurse -Force
选项对我不起作用所以我放弃了copy-item
函数并使用xcopy重新回到下面的内容,因为我仍然希望保持一个单行。最初我与Robocopy捆绑在一起,但它显然正在寻找文件扩展名,因为我的很多都没有扩展名,所以它认为它是一个目录。
$filelist = @("C:\Somepath\test\location\here\file","C:\Somepath\test\location\here2\file2")
$filelist | % { echo f | xcopy $_ $($_.Replace("somepath", "somepath_NEW")) }
希望它有所帮助。
答案 8 :(得分:0)
我修改了@FrinkTheBrave的答案,还创建了子目录并解析了相对路径:
$src_root = Resolve-Path("./source/path/")
$target_root = Resolve-Path("./target/path/")
$glob_filter = "*.*"
Get-ChildItem -path $src_root -filter $glob_filter -recurse |
ForEach-Object {
$target_filename=($_.FullName -replace [regex]::escape($src_root),$target_root)
$target_path=Split-Path $target_filename
if (!(Test-Path -Path $target_path)) {
New-Item $target_path -ItemType Directory
}
Copy-Item $_.FullName -destination $target_filename
}
答案 9 :(得分:0)
$file | Copy-Item -Destination (New-Item -Force -Type Directory -Path $directoryName)