0

I have a series of folders in a source directory that I need to recreate in another environment. The source folder look like this:

C:\temp\stuff\folder01\
C:\temp\stuff\folder02\
C:\temp\stuff\folder03\
C:\temp\stuff\folder02\dog
C:\temp\stuff\folder02\cat

I need to remove the base portion of the path - C:\temp\stuff - and grab the rest of t he path to concatenate with the destination base folder in order to create the folder structure somewhere else.

I have following script. The problem seems to be with the variable $DIR. $DIR never gets assigned the expected "current path minus the base path".

The variable $tmp is assigned something close to the expected folder name. It contains the folder name minus vowels, is split across multiple lines, and includes a bunch of leading whitespace. For example, a folder named folder01 would look like the following:

f
ld
r01

Here's the PowerShell script:

$SOURCES_PATH = "C:\temp\stuff"
$DESTINATION_PATH = "/output001"

Get-ChildItem "$SOURCES_PATH" -Recurse -Directory |
Foreach-Object {

    $tmp = $_.FullName.split("$SOURCES_PATH/")

    $DIR = $_.FullName.split("$SOURCES_PATH/")[1]

    $destination = "$DESTINATION_PATH/$DIR"

    *** code omitted ***
}

I suspect the $DIR appears to be unassigned because the [1] element is whitespace but I'm don't know why there is whitespace and what's happening to the folder name.

What's going on and how do I fix this?

DenaliHardtail
  • 27,362
  • 56
  • 154
  • 233
  • You could replace "C:\temp\stuff" with the destination base folder. Or, for more robustness, use [Path.Combine](https://stackoverflow.com/a/25893843/1115360). – Andrew Morton Aug 21 '20 at 19:46

2 Answers2

0

String.Split("somestring") will split on every occurrence of any of the characters in "somestring", which is why you're seeing the paths being split into many more parts than you're expecting.

I'd suggest using -replace '^base' to remove the leading part of the path:

$SOURCES_PATH = "C:\temp\stuff"
$DESTINATION_PATH = "/output001"

Get-ChildItem "$SOURCES_PATH" -Recurse -Directory |Foreach-Object {

    # This turns "C:\temp\stuff\folder01" into "\folder01"
    $relativePath = $_.FullName -replace "^$([regex]::Escape($SOURCES_PATH))"

    # This turns "\folder01" into "/folder01"
    $relativeWithForwardSlash = $relativePath.Replace('\','/')

    # Concatenate destination root and relative path
    $rootedByDestination = "${DESTINATION_DIR}${relativeWithForwardSlash}"

    # Create/Copy $rootedByDestination here
}

-replace is a regular expression operator, which is why I run [regex]::Escape() against the input path, to double-escape the backslashes :)

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
0

Consider replacing the source path with an empty string. Then you can either concat what's left onto destination path, or use Path::Combine to take care of the concatenation and any separator drama.

Source:

Get-ChildItem | ForEach-Object {
    $destination = [System.IO.Path]::Combine($DESTINATION_PATH, $_.FullName.Replace($SOURCES_PATH, ''))
}