PowerShell 복사 항목 사용 방법 및 구조 유지
디렉토리 구조는 다음과 같습니다.
C:\folderA\folderB\folderC\client1\f1\files
C:\folderA\folderB\folderC\client1\f2\files
C:\folderA\folderB\folderC\client2\f1\files
C:\folderA\folderB\folderC\client2\f2\files
C:\folderA\folderB\folderC\client3\f1\files
C:\folderA\folderB\folderC\client4\f2\files
저는 다의내용복싶다습의 .f1
:\를 가져오려면 Ctmp\에 있는 폴더를 하십시오.
C:\tmp\client1\f1\files
C:\tmp\client2\f1\files
C:\tmp\client3\f1\files
시도해 봤습니다.
Copy-Item -recur -path: "*/f1/" -destination: C:\tmp\
그러나 구조를 제대로 복사하지 않고 내용을 복사합니다.
PowerShell 버전 3.0 이상에서는 다음과 같은 방법으로 간단히 수행할 수 있습니다.
Get-ChildItem -Path $sourceDir | Copy-Item -Destination $targetDir -Recurse -Container
참조: 하위 항목 가져오기
PowerShell:
$sourceDir = 'c:\folderA\folderB\folderC\client1\f1'
$targetDir = ' c:\tmp\'
Get-ChildItem $sourceDir -filter "*" -recurse | `
foreach{
$targetFile = $targetDir + $_.FullName.SubString($sourceDir.Length);
New-Item -ItemType File -Path $targetFile -Force;
Copy-Item $_.FullName -destination $targetFile
}
참고:
- -filter "*"는 아무 일도 하지 않습니다.일부 특정 파일을 복사하려는 경우 설명하기 위해 여기에 있습니다.예: 모든 *.config 파일.
- 여전히 새 항목을 호출해야 합니다.
-Force
폴더 구조를 실제로 만듭니다.
저는 이 문제에 대한 많은 해결책을 찾았는데, 이 모든 것이 단순한 복사 항목 명령이 아니라 약간의 변화였습니다. 중 일부는 3. 3하여 PowerShell 3.0을 이 할 수 .-Container
Copy-Item 파일:
Copy-Item $from $to -Recurse -Container
이것은 실행된 테스트이며 오류가 없으며 대상 폴더가 동일한 폴더 구조를 나타냈습니다.
New-Item -ItemType dir -Name test_copy
New-Item -ItemType dir -Name test_copy\folder1
New-Item -ItemType file -Name test_copy\folder1\test.txt
# NOTE: with no \ at the end of the destination, the file
# is created in the root of the destination, and
# it does not create the folder1 container
#Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2 -Recurse -Container
# If the destination does not exist, this created the
# matching folder structure and file with no errors
Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2\ -Recurse -Container
사용하다xcopy
또는robocopy
둘 다 정확히 그 목적을 위해 설계되었습니다.물론 경로가 파일 시스템 경로일 뿐이라고 가정합니다.
PowerShell을 사용하여 폴더 구조를 올바르게 복사하려면 다음과 같이 하십시오.
$sourceDir = 'C:\source_directory'
$targetDir = 'C:\target_directory'
Get-ChildItem $sourceDir -Recurse | % {
$dest = $targetDir + $_.FullName.SubString($sourceDir.Length)
If (!($dest.Contains('.')) -and !(Test-Path $dest))
{
mkdir $dest
}
Copy-Item $_.FullName -Destination $dest -Force
}
이렇게 하면 디렉터리를 만들고 파일을 복사할 수 있습니다.물론 폴더에 마침표가 있는 경우 위의 Contains() 호출을 수정하거나 언급한 대로 "f1"을 검색하려면 필터를 추가해야 합니다.
그Container
(복사 항목으로) 전환하여 폴더 구조를 유지 관리합니다.즐거운 시간 되세요.
testing>> tree
Folder PATH listing
Volume serial number is 12D3-1A3F
C:.
├───client1
│ ├───f1
│ │ └───files
│ └───f2
│ └───files
├───client2
│ ├───f1
│ │ └───files
│ └───f2
│ └───files
├───client3
│ └───f1
│ └───files
└───client4
└───f2
└───files
testing>> ls client* | % {$subdir = (Join-Path $_.fullname f1); $dest = (Join-Path temp ($_
.name +"\f1")); if(test-path ($subdir)){ Copy-Item $subdir $dest -recurse -container -force}}
testing>> tree
Folder PATH listing
Volume serial number is 12D3-1A3F
C:.
├───client1
│ ├───f1
│ │ └───files
│ └───f2
│ └───files
├───client2
│ ├───f1
│ │ └───files
│ └───f2
│ └───files
├───client3
│ └───f1
│ └───files
├───client4
│ └───f2
│ └───files
└───temp
├───client1
│ └───f1
│ └───files
├───client2
│ └───f1
│ └───files
└───client3
└───f1
└───files
testing>>
파이프나 인라인 스크립팅이 필요 없는 보다 간단한 방법을 찾는 데 시간을 투자한 이후로:
Copy-Item -Path $sourceDir -Destination $destinationDir -Recurse -Container -Verbose
▁a▁다▁also를 제공할 수도 있습니다.-Filter
복사에 대한 조건이 요구되는 경우 인수.
PowerShell 5.1.18362.752와 함께 작동합니다.
출처: https://devblogs.microsoft.com/scripting/powertip-use-powershell-to-copy-items-and-retain-folder-structure/
같은 작업을 수행해야 했기 때문에 다음 명령을 찾았습니다.
XCopy souce_path destination_path /E /C /I /F /R /Y
그리고 당신의 경우:
XCopy c:\folderA\folderB\folderC c:\tmp /E /C /I /F /R /Y
또한 일부 항목을 제외해야 하는 경우 제외 목록이 있는 텍스트 파일을 만듭니다.예:
텍스트 파일 'exclude'를 만듭니다.드라이브 C:\에 txt'를 입력하고 다음을 추가합니다.
.svn
.git
복사 명령은 다음과 같습니다.
XCopy c:\folderA\folderB\folderC c:\tmp /EXCLUDE:c:\exclude.txt /E /C /I /F /R /Y
다음은 원본 파일이 상대적이고 일부 파일만 폴더 구조로 복사하면 되는 기본 질문의 약간 변형입니다.는 이시리실경수있발다습니생할을 할 수 .git diff
변경 사항의 하위 집합을 가지고 있습니다.예.
src/folder1/folder2/change1.txt
src/folder3/change2.txt
->
c:\temp
코드
# omitting foreach($file in $files)
$file = 'src/folder1/folder2/change1.txt'
$tempPath = 'c:\temp'
# Build destination path
$destination = Join-Path $tempPath -ChildPath (Split-Path $file)
# Copy and ensure destination exists
Copy-Item -Path $file -Destination (New-Item -Path $destination -Type Directory -Force)
는 다음과 .
c:\folder\src\folder1\folder2\change1.txt
c:\folder\src\folder3\change2.txt
스크립트의 주요 기술은 폴더 구조를 평가하고 New-Item 명령을 사용하여 폴더 구조가 생성되는지 확인하는 것입니다.
$sourceDir = 'C:\source_directory'
$targetDir = 'C:\target_directory'
Get-ChildItem $sourceDir -Recurse | % {
$dest = $targetDir + $_.FullName.SubString($sourceDir.Length)
If (!($dest.Contains('.')) -and !(Test-Path $dest))
{
mkdir $dest
}
Copy-Item $_.FullName -Destination $dest -Force
}
이 코드는 특히 필터/where-object 메서드와 관련하여 Get-ChildItem을 사용하는 경우에 작동합니다.
그러나 이 코드에는 한 가지 사소한 오류가 있습니다."IF" 문과 다음 코드 "mkdir"를 통해 $targetDir의 폴더가 생성됩니다.나중에 "copy-item" 명령을 실행하면 "copy-dir" 명령을 실행하면 폴더 내에 동일한 폴더가 생성됩니다.
다음은 "Where-Object" 기능을 사용하여 작동한 예입니다.단순히 IF 문을 생략할 수 있습니다.
$Sourcefolder= "C:\temp1"
$Targetfolder= "C:\temp2"
$query = Get-ChildItem $Sourcefolder -Recurse | Where-Object {$_.LastWriteTime -gt [datetime]::Now.AddDays(-1)}
$query | % {
$dest = $Targetfolder + $_.FullName.SubString($Sourcefolder.Length)
Copy-Item $_.FullName -Destination $dest -Force
}
경로가 끝에 "\"로 표시되지 않는지 확인합니다.
아래는 저에게 효과가 있었습니다.
@echo off
setlocal enableextensions disabledelayedexpansion
set "target=e:\backup"
for /f "usebackq delims=" %%a in ("TextFile.txt") do (
md "%target%%%~pa" 2>nul
copy /y "%%a" "%target%%%~pa"
)
목록 내의 각 줄(파일)에 대해 대상 폴더 아래에 읽기 줄에 표시된 것과 동일한 경로를 만듭니다(%%~pa는 %%a가 참조하는 요소의 경로입니다).그런 다음 읽기 파일을 대상 폴더에 복사합니다.
Copy-Item은 사용자가 예상하는 것을 수행하지 않습니다. Invoke-Expression은 명령줄 명령을 호출하고 파워셸 변수를 사용할 수 있습니다.디렉토리가 복사되도록 (빈 디렉토리도 포함) /Y와 함께 good-old xcopy 명령을 사용하여 프롬프트 표시를 억제하고 덮어쓰기를 확인합니다.
$sourceDir = "c:\source\*"
$targetDir = "c:\destination\"
Invoke-Expression "xcopy $sourceDir $targetDir /E /Y"
일반적으로 복사 항목은 대상 폴더가 이미 존재하는 한 이 작업을 수행합니다.문서가 제가 테스트를 통해 검증한 것과 일치하지 않습니다.대상 경로의 후행 슬래시는 이 문제를 해결하지 않습니다.폴더 계층을 복사할 때 -Recurse를 사용해야 합니다.Container 매개 변수는 기본적으로 true로 설정되어 있으므로 이를 해제할 수 있습니다.
질문에서 명명된 하위 폴더를 기준으로 복사할 파일 목록을 필터링하고 있습니다.Copy-Item의 Path 속성에 대해서는 작동하지만, 문제는 대상 폴더(클라이언트*)가 존재하지 않기 때문에 파일이 대상 폴더의 루트에 배치된다는 것입니다.대부분의 다른 답변은 이 시나리오를 구체적으로 다루지 않으므로 질문에 대답하지 않습니다.솔루션을 달성하려면 다음 두 단계를 수행해야 합니다.
- 복사할 파일 선택
- 대상 폴더가 있는지 확인하면서 선택한 파일을 대상 폴더에 복사
$source = 'C:\FolderA\FolderB\FolderC'
$dest = 'C:\tmp'
# Only need the full name
$files = Get-ChildItem -Path $source -Recurse -File | Where-Object { $_.FullName -match '^.+\\client\d\\f1\\.+\..+$' } | ForEach-Object { $_.FullName }
# Iterate through the list copying files
foreach( $file in $files ) {
$destFile = $file.Replace( $source, $dest )
$destFolder = Split-Path -Path $destFile -Parent
# Make sure the destination folder for the file exists
if ( -not ( Test-Path -Path $destFolder ) ) {
New-Item -Path ( Split-Path -Path $destFolder -Parent ) -Name ( Split-Path -Path $destFolder -Leaf ) -ItemType Directory -Force
}
Copy-Item -Path $file -Destination $destFolder
}
$source ="c:\"
$destination="c:\tmp"
sl $source
md $destination
ls "." -rec -Filter *.zip | %{
$subfolder=($_.FullName)
$pathtrim=($subfolder -split [regex]::escape([system.io.path])::directoryseperatorchar)[-3] # update -2,-3 here to match output, we need 'client1\f1\files' here
echo $pathtrim
$finaldest=Join-Path -Path $destination -ChildPath $pathtrim
cp $source $finaldest -Verbose
}
폴더 구조를 유지하는 디렉터리에서 모든 파일을 복사하는 다음 기능을 만들었습니다.그런 다음 폴더 구조가 시작될 시작 색인을 지정할 수 있습니다.
function Copy-FileKeepPath {
param (
$filter,$FileToCopy,$des,$startIndex
)
Get-ChildItem -Path $FileToCopy -Filter $filter -Recurse -File | ForEach-Object {
$fileName = $_.FullName
#Remove the first part to ignore from the path.
$newdes=Join-Path -Path $des -ChildPath $fileName.Substring($startIndex)
$folder=Split-Path -Path $newdes -Parent
$err=0
#check if folder exists"
$void=Get-Item $folder -ErrorVariable err -ErrorAction SilentlyContinue
if($err.Count -ne 0){
#create when it doesn't
$void=New-Item -Path $folder -ItemType Directory -Force -Verbose
}
$void=Copy-Item -Path $fileName -destination $newdes -Recurse -Container -Force -Verbose
}
}
다음과 같이 사용합니다.
Copy-FileKeepPath -FileToCopy 'C:\folderA\folderB\folderC\client1\f1\' -des "C:\tmp" -filter * -startIndex "C:\folderA\folderB\folderC\".Length
라이브러리 파일(플랫폼 및 빌드 유형이 서로 다름)만 공유하려는 비슷한 요구사항이 있었습니다.PowerShell 스크립트를 작성하려고 했는데 "SyncBackFree" 도구를 사용하여 1분 이내에 완료할 수 있다는 것을 깨달았습니다.예상대로 작동했습니다.
프로파일 작성
소스 및 대상 폴더 선택
하위 디렉토리 및 파일 선택을 누릅니다.
왼쪽 "필터 변경" 클릭
파일 확장자("*.lib") 및 "*"(폴더 구조용) 추가
언급URL : https://stackoverflow.com/questions/5432290/how-to-use-powershell-copy-item-and-keep-structure
'programing' 카테고리의 다른 글
Android에서 ScrollView를 사용하는 방법은 무엇입니까? (0) | 2023.07.25 |
---|---|
HTML에서 CDATA란 무엇입니까? (0) | 2023.07.25 |
많은 디스크 공간을 차지하는 Android SDK 폴더.모든 시스템 이미지를 보관해야 합니까? (0) | 2023.07.25 |
사용자 테이블에서 일치하는 행을 찾을 수 없습니다. (0) | 2023.07.25 |
파워셸 언로드 모듈...완전히. (0) | 2023.07.25 |