2

Basically I have a path "root/main/EVILFOLDER/first/second/third/etc" And I want to remove EVILFOLDER/ specifically the 3rd segment of the path. The thing is EVILFOLDER could be anything so I can't just hardcode it as such and the path length and number of "/" could be any varying length.

I have this, and it works, but elegant it is not.

$path = "root/main/EVILFOLDER/first/second/third/etc"
$basePath = "{0}/{1}/" -f $path.Split('/')
$subFolder = "{3}/" -f $shortPath.Split('/')
$subFolderIndex = $shortPath.IndexOf($subFolder)
$newPath = $basePath + $shortPath.Substring($subFolderIndex)

Ultimately I was hoping I could write it as somethingl ike "{0}/{1}/{3}... " to get the rest of the path listing. Ideas?

3 Answers3

1

Give this a try:

'root/main/EVILFOLDER/first/second/third/etc',
'root/main/EVILFOLDEREVILFOLDEREVILFOLDER/first/',
'root/main/EVILFOLDEREVILFOLDEREVILFOLDER',
'root/main/zzz/first/second/third/etc',
'root/main/tinyEvil/aaaa/bbbb/cccc/dddd/eee' | ForEach-Object {
    $good1, $good2, $notgood, $good3 = $_ -split '(?=/)',4
    $newName = -join( $good1, $good2, $good3 )

    [PSCustomObject]@{
        OldName = $_
        NewName = $newName
    }
}

# Results

OldName                                         NewName
-------                                         -------
root/main/EVILFOLDER/first/second/third/etc     root/main/first/second/third/etc
root/main/EVILFOLDEREVILFOLDEREVILFOLDER/first/ root/main/first/
root/main/EVILFOLDEREVILFOLDEREVILFOLDER        root/main
root/main/zzz/first/second/third/etc            root/main/first/second/third/etc
root/main/tinyEvil/aaaa/bbbb/cccc/dddd/eee      root/main/aaaa/bbbb/cccc/dddd/eee

Basically we care about preserving $good1 and $good2, it may or may not be a $good3 after $notGood but this should be able to handle it.

Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
  • So is the `-split '(?=/)',4` a way of grabbing everything in $good3? i.e. ` $newpath = "{0}/{1}/{3}" -f $path.Split('?=/',4) ` – David at Fishtank Dec 07 '21 at 22:18
  • @DavidAustin there will be a `$good3` as long as the path has 4 or more segments. If the path has 3 segments that variable would be `null` for example the one from my answer `root/main/EVILFOLDEREVILFOLDEREVILFOLDER` only has 3 segments and it gets converted to `root/main`. – Santiago Squarzon Dec 07 '21 at 22:24
  • 1
    `$newPath = "{0}/{1}/{3}" -f $shortPath.Split('?=/',4)` This is what I ended up going with. – David at Fishtank Dec 07 '21 at 22:28
  • @DavidatFishtank I have edited my answer to help you compare and maybe give you a perspective of what I mean. – Santiago Squarzon Dec 07 '21 at 22:28
  • @DavidatFishtank note that, the `.split(..)` does not understand `regex`, `?=/` will mean literally that and using string formatting can lead to errors the way you're using it. – Santiago Squarzon Dec 07 '21 at 23:44
0
$data = 'root/main/EVILFOLDER/first/second/third/etc' -split "/";
$data[0,1]+$data[3..$data.length] -join "/"
betelgeuse
  • 1,136
  • 3
  • 13
  • 25
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 08 '21 at 09:08
0

-split is fine but this regular expression should do the trick too :

$NewPath = $Path -replace "^([^/]+/[^/]+)/[^/]+(.*)", '$1$2'

^ start of the string

([^/]+/[^/]+) first block to keep where [^/]+ will keep any chars (at least 1) but /, so this corresponding to "any chars/any chars"

/[^/]+ chars to remove ("/any chars except /")

(.*) second block to keep : "any chars (can be no char)"

replace with $1$2 corresponding to blocks to keep 1 and 2

If your path uses backslashes, then you need to escape them in the regex : ^([^\\]+\\[^\\]+)\\[^\\]+(.*)

CFou
  • 978
  • 3
  • 13