How can one copy an entire folder structure but only select some folders several subdirectories down based on the folder name by two different strings ('Touch' or 'mpr') ?
the files I need are in e.g.:
"C:\Users\Desktop\shizzle\mro\pre\subject_01\Touch"
but there are two Timepoint-folders (Pre and Post) and several subjects, hence I have tried a higher directory:
$includes = 'Touch|mpr'
Get-ChildItem "C:\Users\Desktop\shizzle\mro" -Directory |
Where-Object{$_.Name -match $includes} |
Copy-Item -Destination "C:\Users\shizzle\Desktop\shi_data6" -Recurse -Force
which works perfectly, but only if the searched folders are in the specified directory and not several subdirectories down (so it would only work in C:\Users\Desktop\shizzle\mro\pre\subject_01
).
Get-ChildItem "C:\Users\shizzle\Downloads\copy_test\copy_test\mro" -Recurse | Where-Object{$_.Name -match $includes} | Copy-Item -Destination "C:\Users\shizzle\Downloads\test_shi10" -Recurse -Force
doesnt not keep up the folder structure.
The folder structure looks like this:
C:\Users\Desktop\shizzle\mro\
+---pre
| +---subject_01
| | +---dontcopythisfolder
| | +---dontcopythisfolder
| | +---0024_63_Touch
| | | File_1.txt
| | | File_2.txt
| | | File_3.txt
| | +---dontcopythisfolder
| | \---654_mpr_8364
| | File_1.txt
| | File_2.txt
| | File_3.txt
| \---subject_02
| +---dontcopythisfolder
| +---dontcopythisfolder
| +---0024_63_Touch
| | File_1.txt
| | File_2.txt
| | File_3.txt
| +---dontcopythisfolder
| \---654_mpr_8364
| File_1.txt
| File_2.txt
| File_3.txt
\---post
+---subject_01
| +---dontcopythisfolder
| +---dontcopythisfolder
| +---0024_63_Touch
| | File_1.txt
| | File_2.txt
| | File_3.txt
| +---dontcopythisfolder
| \---654_mpr_8364
| File_1.txt
| File_2.txt
| File_3.txt
\---subject_02
+---dontcopythis folder
+---dontcopythisfolder
+---0024_63_Touch
| File_1.txt
| File_2.txt
| File_3.txt
+---dontcopythisfolder
\---654_mpr_8364
File_1.txt
File_2.txt
File_3.txt
You can try this:
$sourcePath = 'D:\Test' # 'C:\Users\Desktop\shizzle\mro'
$Destination = 'D:\Data' # 'C:\Users\shizzle\Desktop\shi_data6'
$includes = 'Touch|mpr'
Get-ChildItem -Path $sourcePath -Recurse -Directory |
Where-Object{$_.Name -match $includes} |
ForEach-Object {
$targetPath = Join-Path -Path $Destination -ChildPath $_.Parent.FullName.Substring($sourcePath.Length)
$null = New-Item -Path $targetPath -ItemType Directory -Force
$_ | Copy-Item -Destination $targetPath -Recurse -Force
}
Instead of using the Substring()
method above, you can also use regex -replace
to construct the target path.
However, keep in mind that a path contains characters that have special meaning for regex, so you should then use the [regex]::Escape()
'd version of the source path, and anchor it to the beginning of the string with ^
:
$sourcePath = 'D:\Test' # 'C:\Users\Desktop\shizzle\mro'
$Destination = 'D:\Data' # 'C:\Users\shizzle\Desktop\shi_data6'
$includes = 'Touch|mpr'
# if you want to use regex `-replace` instead, use this:
$escapedSource = '^{0}' -f [regex]::Escape($sourcePath)
Get-ChildItem -Path $sourcePath -Recurse -Directory |
Where-Object{$_.Name -match $includes} |
ForEach-Object {
$targetPath = Join-Path -Path $Destination -ChildPath ($_.FullName -replace $escapedSource)
$null = New-Item -Path $targetPath -ItemType Directory -Force
$_ | Copy-Item -Destination $targetPath -Recurse -Force
}
Below the results of my test (using different paths of course..)
Source
D:\TEST
+---post
| +---subject_01
| | +---0024_63_Touch
| | | File1.txt
| | | File2.txt
| | |
| | +---654_mpr_8364
| | | File1.txt
| | | File2.txt
| | |
| | +---dontcopythisfolder
| | \---ignorethisonetoo
| \---subject_02
| +---0024_63_Touch
| | File1.txt
| | File2.txt
| |
| +---654_mpr_8364
| | File1.txt
| | File2.txt
| |
| +---dontcopythisfolder
| \---ignorethisonetoo
\---pre
+---subject_01
| +---0024_63_Touch
| | File1.txt
| | File2.txt
| |
| +---654_mpr_8364
| | File1.txt
| | File2.txt
| |
| +---dontcopythisfolder
| \---ignorethisonetoo
\---subject_02
+---0024_63_Touch
| File1.txt
| File2.txt
|
+---654_mpr_8364
| File1.txt
| File2.txt
|
+---dontcopythisfolder
\---ignorethisonetoo
Destination
D:\DATA
+---post
| +---subject_01
| | +---0024_63_Touch
| | | File1.txt
| | | File2.txt
| | |
| | \---654_mpr_8364
| | File1.txt
| | File2.txt
| |
| \---subject_02
| +---0024_63_Touch
| | File1.txt
| | File2.txt
| |
| \---654_mpr_8364
| File1.txt
| File2.txt
|
\---pre
+---subject_01
| +---0024_63_Touch
| | File1.txt
| | File2.txt
| |
| \---654_mpr_8364
| File1.txt
| File2.txt
|
\---subject_02
+---0024_63_Touch
| File1.txt
| File2.txt
|
\---654_mpr_8364
File1.txt
File2.txt