Powershell 2 copy-item如果不存在则创建一个文件夹

问题描述 投票:56回答:8
$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\

powershell copy powershell-v2.0
8个回答
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
    } 
}

2
投票

我最喜欢的是使用.Net [IO.DirectoryInfo]类,它负责一些逻辑。我实际上使用它来解决许多类似的脚本问题。它有一个.Create()方法,可以创建不存在的目录,如果有的话也没有错误。

由于这仍然是一个两步问题,我使用foreach别名来保持简单。对于单个文件:

[IO.DirectoryInfo]$to |% {$_.create(); cp $from $_}

至于你的多文件/目录匹配,我会使用RoboCopy而不是xcopy。从你的删除“*”,只需使用:

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

2
投票

这是一个适合我的例子。我有一个文本文件中大约500个特定文件的列表,包含在大约100个不同的文件夹中,我应该将其复制到备份位置,以防以后需要这些文件。文本文件包含完整路径和文件名,每行一个。就我而言,我想从每个文件名中删除Drive letter和第一个子文件夹名称。我想将所有这些文件复制到我指定的另一个根目标文件夹下的类似文件夹结构。我希望其他用户觉得这很有帮助。

# 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 }
}

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")) }

希望它可以帮助某人。

© www.soinside.com 2019 - 2024. All rights reserved.