Sean Perryman
Sean Perryman

Reputation: 251

Properly Trimming and Escaping a String with a Backslash Separator in PowerShell

I've got an array of directories that present as such:

C:\Parent\Child\Child\_Grandchild

Some children are deeper than others. I need to trim off the

C:\Parent\

and the

\_Grandchild

into an array consisting of

Child, Child

but am constantly having PS strip off leading characters. It seems to be mainly 1's, A's, C's, and P's, but could be others (those are the ones at the top of the list so I notice them). Here is the code I am using, I am certain I am using split incorrectly but cannot figure out how to get it to work as needed.

$a # <-- An array item in a foreach loop
$b = $a.TrimStart('C:\Parent\');
$c = $b.TrimEnd('\_Grandchild');
$c_split = $c -split '\\';

This code seems to often produce results like the following

$c_split[0] = 'hild'; # (or 'ild' in some cases, depending on the starting characters)
$c_split[1] = 'Child';
$c_split[2] = 'Child';

and so on. I figured it was something with my initial TrimStart, but viewing $b during the process looks just fine, just as you would expect. I've tried leaving the trailing \ on the first trim but that didn't seem to solve the problem either.

Upvotes: 0

Views: 2758

Answers (3)

kdh
kdh

Reputation: 84

Something like this maybe:

$path = "C:\Parent\Child\Child\_Grandchild"
$split_path = $path.split("\")
$modified_path = $split_path[2..($split_path.length-2)]

Going on the assumption that you always want to remove "c:\whatever" from the start and the final directory.

Upvotes: 0

bunzab
bunzab

Reputation: 389

This could be a one liner. Maybe a tad messy but works with your sample data. Using IO.Path you can remove the drive root, use a regex to replace everything up to the first backslash, use io.path again to remove last folder, trimend to remove the last \ and split.

$c_split = ($a.Replace([io.path]::GetPathRoot($a),"") -replace "^[^\\]*\\","").Replace([io.path]::GetFileName($a),"").TrimEnd("\").Split("\") 

Upvotes: 0

SomeShinyObject
SomeShinyObject

Reputation: 7811

Without some better test data it's hard to determine what you are really going for but I might have something. If you are just wanting to remove C:\Parent and \_GrandChild or at least the last child in the directory chain, the following will work:

# Assumed test data
$Directories = @(
    "C:\Parent\Child\Child\_Grandchild",
    "C:\Parent\Child\Hulk\_Grandchild",
    "C:\Parent\Child\DareDevil\Child\Child\_Grandchild",
    "C:\Parent\Child\DoctorWho\Child\_Grandchild",
    "C:\Parent\Child\DareDevil\Child\FrenchBread\_Grandchild"
)

$Directories | ForEach-Object {
    $Path = $_
    $Path = Split-Path -Path $Path -NoQualifier #Remove the C:
    $Path = Split-Path -Path $Path # Remove the last portion
    # Here you have "\Parent\..." excluding the _Grandchild portion

    # Split it and then assign the first value to null to disguard
    $Null, $Path = $Path.Split("\")
    # Path is your array of items you want
}

Upvotes: 2

Related Questions