0

I have a path inside a txt file that needs to be manipulated, something like:

C:\Jenkins\Automation\Blah\Foo\Bar\646433\Schema\test\473289_12321.ps1 C:\Jenkins\Automation\Blah\Foo\Bar\2112\Schema\QA\473289_123211.ps1

I want to replace everything before the 7th backslash and then replace it with C:\Question. I was doing something similar in Powershell via:

(Get-Content $FullEnvSQLFilePath) |  #get the content
Foreach-Object {$_ -replace [Regex]::Escape($StringToReplace), "$StringReplaceValue"} | #look for the string and replace

This worked fine when I knew what the exact verbiage was to look for. We now don't know that but we will want to remove everything before the 7th backslash and replace it with a value. Reverse order works fine too. I wasn't able to have much luck in Powershell via substring doing this. Thanks.

Ali Razeghi - AWS
  • 722
  • 1
  • 6
  • 19
  • 1
    Why restricting to 7th backslash? In case you would relocate your powershell script elsewhere you will have to use 6th backslash instead. I'd say look [here](http://stackoverflow.com/questions/10972589/get-relative-path-of-files-in-sub-folders-from-the-current-directory) to get relative path to some root location, then you can use that path to form correct destination location like [here](http://stackoverflow.com/questions/30573854/powershell-copy-files-and-folders/30574964#30574964). – Vesper Jun 02 '15 at 06:36
  • Thanks Vesper, let me look into that. – Ali Razeghi - AWS Jun 02 '15 at 17:46

2 Answers2

2

One option:

$text = 
'C:\Jenkins\Automation\Blah\Foo\Bar\646433\Schema\test\473289_12321.ps1',
'C:\Jenkins\Automation\Blah\Foo\Bar\2112\Schema\QA\473289_123211.ps1'

$text | foreach {'C:\Question\{0}' -f $_.split('\',8)[-1]}
C:\Question\Schema\test\473289_12321.ps1
C:\Question\Schema\QA\473289_123211.ps1
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • does this perform faster than a regex? – Vincent De Smet Jun 02 '15 at 23:12
  • Haven't benchmarked it, but I'd expect it would. Typically string method operations are faster than PS operators, and among those operators, the regex operations (-match, -replace, -split) tend to be the slowest. – mjolinor Jun 03 '15 at 00:01
  • Thank you. I have a problem where line 1 is PRINT c:\blah\blah\blah etc. My process removes everything as soon as it finds 7 backslashes in a line. Can I have it do the replace ONLY if either the line starts with :R or if it doesn't start with PRINT and it matches 7 backslashes? – Ali Razeghi - AWS Jun 03 '15 at 16:36
  • That's getting outside the range of the original question. I'd post a new question for that. – mjolinor Jun 03 '15 at 17:55
1

this ([^\\]*\\){7} regex looks 7 times for a capture group ending on a backslash and replaces it.

UPDATED: .:\\([^\\]*\\){6} regex looks for strings that look like paths starting at any root drive .:\ followed by 6 times a capture group ending on a backslash based on your comment

$text = @"
C:\Jenkins\Automation\Blah\Foo\Bar\646433\Schema\test\473289_12321.ps1
C:\Jenkins\Automation\Blah\Foo\Bar\2112\Schema\QA\473289_123211.ps1
PRINT C:\Jenkins\Automation\Blah\Foo\Baz\2112\Schema\QA\473289_123212.ps1
C:\Jenkins\Automation\Blah\Foo\quux\2112\Schema\QA\473289_123213.ps1
"@
#depending on how you get the text (single string or array)
#$text.Split("`n") | % { $_ -Replace '.:\\([^\\]*\\){6}','C:\Example\' }
$text -Replace ".:\\([^\\`n]*\\){6}","C:\Example\"

Result:

C:\Example\Schema\test\473289_12321.ps1
C:\Example\Schema\QA\473289_123211.ps1
PRINT C:\Example\Schema\QA\473289_123212.ps1
C:\Example\Schema\QA\473289_123213.ps1
Vincent De Smet
  • 4,859
  • 2
  • 34
  • 41
  • if you use `Get-Content` you may not need the split on newline and `For-EachObject` (`%`) script block and apply regex replace direct. – Vincent De Smet Jun 02 '15 at 07:59
  • I excluded newline in capture group, so `%` is no longer needed – Vincent De Smet Jun 02 '15 at 08:13
  • Thank you. I have a problem where line 1 is PRINT c:\blah\blah\blah etc. My process removes everything as soon as it finds 7 backslashes in a line. Can I have it do the replace ONLY if either the line starts with :R or if it doesn't start with PRINT and it matches 7 backslashes? – Ali Razeghi - AWS Jun 03 '15 at 16:36
  • 1
    Easy to change the regex from `([^\\`n]*\\){7}` to `.:\\([^\\`n]*\\){7}`, which is one of the reasons why it's better to go with a clear & easy to maintain regex. Even if you might sacrifice a tiny bit of performance – Vincent De Smet Jun 05 '15 at 04:50