Powershell 2 copy-элемент, который создает папку, если она не существует
$from = "something XLS10_04_22*"
$to = "c:out XLS10_04_22"
copy-item $from $to -Recurse
это работает, если c:out1 XLS2010_04_22 существует . Возможно ли с помощью одной команды создать "c:out1 XLS2010_04_22" если он не существует.
7 ответов:
в PowerShell 2.0 по-прежнему невозможно получить командлет Copy-Item для создания папки назначения, вам понадобится такой код:
$destinationFolder = "C:\My Stuff\Subdir" if (!(Test-Path -path $destinationFolder)) {New-Item $destinationFolder -Type Directory} Copy-Item "\server1\Upgrade.exe" -Destination $destinationFolderЕсли вы используете -Recurse в Copy-Item, он создаст все подпапки исходной структуры в месте назначения, но он не создаст фактическую папку назначения, даже с-Force.
в PowerShell 3 и выше я использую Copy-Item с New-Item.
copy-item -Path $file -Destination (new-item -type directory -force ("C:\Folder\sub\sub\" + $newSub)) -force -ea 0Я не пробовал его в версии 2.
мой любимый, чтобы использовать .Net [IO.DirectoryInfo] класс,который заботится о некоторой логике. Я на самом деле использую это для многих подобных задач сценариев. У него есть .Create () метод, который создает каталоги, которые не существуют, без ошибок, если они есть.
поскольку это все еще двухэтапная проблема, я использую псевдоним foreach, чтобы сохранить его простым. Для отдельных файлов:
[IO.DirectoryInfo]$to |% {$_.create(); cp $from $_}что касается вашего соответствия нескольких файлов/каталогов, я бы использовал RoboCopy над xcopy. Удалять "*"от вашего ОТ и просто использовать:
RoboCopy.exe $from $to *вы все еще можете добавить /r (Recurse), /e (Recurse включая пустой), и есть 50 других полезных переключателей.
Edit: оглядываясь назад, это кратко, но не очень читаемо, если вы не используете код часто. Обычно я его разделяю на два, вот так:
([IO.DirectoryInfo]$to).Create() cp $from $toи DirectoryInfo - это тип родительского свойства FileInfo, так что если ваш $to файл, вы можете использовать их вместе:
([IO.FileInfo]$to).Parent.Create() cp $from $to
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 } }
Я споткнулся здесь дважды, и в этот последний раз была уникальная ситуация, и хотя я канаву с помощью
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")) }надеюсь, что это поможет кому-то.
Comments