존재하지 않는 경우 폴더를 생성하는 Powershell 2 복사 항목
$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\
존재하지 않는 경우 단일 명령으로 만들 수 있습니까?
예, -Force
매개 변수를 추가합니다 .
copy-item $from $to -Recurse -Force
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를 사용하더라도 실제 대상 폴더는 생성되지 않습니다.
PowerShell 3 이상에서는 New-Item과 함께 Copy-Item을 사용합니다.
copy-item -Path $file -Destination (new-item -type directory -force ("C:\Folder\sub\sub\" + $newSub)) -force -ea 0
버전 2에서 시도하지 않았습니다.
$filelist | % {
$file = $_
mkdir -force (Split-Path $dest) | Out-Null
cp $file $dest
}
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
}
}
My favorite is to use the .Net [IO.DirectoryInfo] class, which takes care of some of the logic. I actually use this for a lot of similar scripting challenges. It has a .Create() method that creates directories that don't exist, without errors if they do.
Since this is still a two step problem, I use the foreach alias to keep it simple. For single files:
[IO.DirectoryInfo]$to |% {$_.create(); cp $from $_}
As far as your multi file/directory match, I would use RoboCopy over xcopy. Remove the "*" from your from and just use:
RoboCopy.exe $from $to *
You can still add the /r (Recurse), /e (Recurse including Empty), and there are 50 other useful switches.
Edit: Looking back at this it is terse, but not very readable if you are not using the code often. Usually I have it split into two, like so:
([IO.DirectoryInfo]$to).Create()
cp $from $to
Also, DirectoryInfo is the type of the Parent property of FileInfo, so if your $to is a file, you can use them together:
([IO.FileInfo]$to).Parent.Create()
cp $from $to
Here's an example that worked for me. I had a list of about 500 specific files in a text file, contained in about 100 different folders, that I was supposed to copy over to a backup location in case those files were needed later. The text file contained full path and file name, one per line. In my case, I wanted to strip off the Drive letter and first sub-folder name from each file name. I wanted to copy all these files to a similar folder structure under another root destination folder I specified. I hope other users find this helpful.
# 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 }
}
I have stumbled here twice, and this last time was a unique situation and even though I ditch using copy-item
I wanted to post the solution I used.
Had a list of nothing but files with the full path and in majority of the case the files have no extensions. the -Recurse -Force
option would not work for me so I ditched copy-item
function and fell back to something like below using xcopy as I still wanted to keep it a one liner. Initially I tied with Robocopy but it is apparently looking for a file extension and since many of mine had no extension it considered it a directory.
$filelist = @("C:\Somepath\test\location\here\file","C:\Somepath\test\location\here2\file2")
$filelist | % { echo f | xcopy $_ $($_.Replace("somepath", "somepath_NEW")) }
Hope it helps someone.
'Nice programing' 카테고리의 다른 글
며칠, 몇 시간, 몇 주 및 몇 달 후에 시간 범위를 반복하는 방법은 무엇입니까? (0) | 2020.12.03 |
---|---|
지정된 div 내의 링크에 target =“_ blank”를 어떻게 추가합니까? (0) | 2020.12.02 |
DEXtoJar 사용 방법 (0) | 2020.12.02 |
괄호 사이의 텍스트 제거 PHP (0) | 2020.12.02 |
Magento 시스템 구성에서 데이터를 가져 오는 방법 (0) | 2020.12.02 |