Alex1088
Alex1088

Reputation: 147

Powershell replace last two occurrences of a '/' in file path with '.'

I have a filepath, and I'm trying to remove the last two occurrences of the / character into . and also completely remove the '{}' via Powershell to then turn that into a variable.

So, turn this:

xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx

Into this:

xxx-xxx-xx\xxxxxxx\x\xxxx-xxxxx-xxxx.xxxxx.xxxxx

I've tried to get this working with the replace cmdlet, but this seems to focus more on replacing all occurrences or the first/last occurrence, which isn't my issue. Any guidance would be appreciated!

Edit:

So, I have an excel file and i'm creating a powershell script that uses a for each loop over every row, which amounts to thousands of entries. For each of those entries, I want to create a secondary variable that will take the full path, and save that path minus the last two slashes. Here's the portion of the script that i'm working on:

Foreach($script in $roboSource)
   {
    $logFileName = "$($script.a).txt".Replace('(?<=^[^\]+-[^\]+)-','.')
   } 

$script.a will output thousands of entries in this format: xxx-xxx-xx\xxxxxxx\x{xxxx-xxxxx-xxxx}\xxxxx\xxxxx Which is expected.

I want $logFileName to output this: xxx-xxx-xx\xxxxxxx\x\xxxx-xxxxx-xxxx.xxxxx.xxxxx

I'm just starting to understand regex, and I believe the capture group between the parenthesis should be catching at least one of the '\', but testing attempts show no changes after adding the replace+regex.

Please let me know if I can provide more info.

Thanks!

Upvotes: 1

Views: 589

Answers (3)

mklement0
mklement0

Reputation: 439822

A 2-step approach is simplest in this case:

# Input string.
$str = 'xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx'

# Get everything before the "{"
$prefix = $str -replace '\{.+'

# Get everything starting with the "{", remove "{ and "}", 
# and replace "\" with "."
$suffix = $str.Substring($prefix.Length) -replace '[{}]' -replace '\\', '.'

# Output the combined result (or assign to $logFileName)
$prefix + $suffix

If you wanted to do it with a single -replace operation (with nesting), things get more complicated:

Note: This solution requires PowerShell Core (v6.1+)

$str -replace '(.+)\{(.+)\}(.+)',
  { $_.Groups[1].Value + $_.Groups[2].Value + ($_.Groups[3].Value -replace '\\', '.') }

Also see the elegant PS-Core-only -split based solution with a negative index (to split only a fixed number of tokens off the end) in Mathias R. Jessen's helpful answer.

Upvotes: 3

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174825

You can do this in two fairly simply -replace operations:

  • Remove { and }
  • Replace the last two \:
$str = 'xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx'
$str -replace '[{}]' -replace '\\([^\\]*)\\([^\\]*)$','.$1.$2'

The second pattern matches:

\\         # 1 literal '\'
(          # open first capture group
  [^\\]*   # 0 or more non-'\' characters
)          # close first capture group
\\         # 1 literal '\'
(          # open second capture group
  [^\\]*   # 0 or more non-'\' characters
)          # close second capture group
$          # end of string

Which we replace with the first and second capture group values, but with . before, instead of \: .$1.$2


If you're using PowerShell Core version 6.1 or newer, you can also take advantage of right-to-left -split:

($str -replace '[{}]' -split '\\',-3) -join '.'

-split '\\',-3 has the same effect as -split '\\',3, but splitting from the right rather than the left.

Upvotes: 5

Esperento57
Esperento57

Reputation: 17492

try this

$str='xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx'

#remove  bracket and split for get array
$Array=$str -replace '[{}]' -split '\\'

#take all element except 2 last elements, and concat after last elems
"{0}.{1}.{2}" -f ($Array[0..($Array.Length -3)] -join '\'), $Array[-2], $Array[-1]

Upvotes: 2

Related Questions