0

I'm trying to make using of String.Substring() to replace every string with its substring from a certain position. I'm having a hard time figuring out the right syntax for this.

$dirs = Get-ChildItem -Recurse $path | Format-Table -AutoSize -HideTableHeaders -Property @{n='Mode';e={$_.Mode};width=50}, @{n='LastWriteTime';e={$_.LastWriteTime};width=50}, @{n='Length';e={$_.Length};width=50}, @{n='Name';e={$_.FullName -replace "(.:.*)", "*($(str($($_.FullName)).Substring(4)))*"}} | Out-String -Width 40960

I'm referring to the following expression

e={$_.FullName -replace "(.:.*)", "*($(str($($_.FullName)).Substring(4)))*"}}

The substring from the 4th character isn't replacing the Full Name of the path. The paths in question are longer than 4 characters.

The output is just empty for the Full Name when I run the script. Can someone please help me out with the syntax

EDIT The unaltered list of strings (as Get-ChildItem recurses) would be

D:\this\is\where\it\starts
D:\this\is\where\it\starts\dir1\file1
D:\this\is\where\it\starts\dir1\file2
D:\this\is\where\it\starts\dir1\file3
D:\this\is\where\it\starts\dir1\dir2\file1

The $_.FullName will therefore take on the value of each of the strings listed above. Given an input like D:\this\is or D:\this\is\where, then I'm computing the length of this input (including the delimiter \) and then replacing $_.FullName with a substring beginning from the nth position where n is the length of the input.

If input is D:\this\is, then length is 10. Expected output is

\where\it\starts
\where\it\starts\dir1\file1
\where\it\starts\dir1\file2
\where\it\starts\dir1\file3
\it\starts\dir1\dir2\file1
5
  • 1
    Can you edit your post and give an example of what the unaltered string is and what the desired string is? Having a hard time understanding exactly what you are looking to do. Commented Mar 14, 2018 at 12:33
  • In addition, please explain what you are trying to achieve. It looks like you are trying to build some kind of summary report; maybe there's better a way. Commented Mar 14, 2018 at 12:35
  • 1
    If you just want to remove the leading D:\ you should do exactly that: $_.FullName -replace '^.:\\'. If you want to remove a particular parent path you could do this: $_.FullName -replace ('^' + [regex]::Escape($parent)). If you must use a fixed length you could do this: $_.FullName -replace '^.{4}'. Commented Mar 14, 2018 at 12:40
  • So do you just want to remove the drive and the first path of "$Path"? You can make that dynamic by doing ".Substring($Path.Length)" Commented Mar 14, 2018 at 12:56
  • Thanks @AnsgarWiechers, it was so simple :), being a newbie to Powershell and not all that familiar with regex, I guess I decided to use the most complicated solution to achieve this. If you post this as an answer, I can mark this as SOLVED :) Commented Mar 14, 2018 at 12:59

2 Answers 2

1

If you want to remove a particular prefix from a string you can do so like this:

$prefix = 'D:\this\is'
...
$_.FullName -replace ('^' + [regex]::Escape($prefix))

To remove a prefix of a given length you can do something like this:

$len = 4
...
$_.FullName -replace "^.{$len}"
Sign up to request clarification or add additional context in comments.

Comments

0

When having trouble, simplify:

This function will do what you are apparently trying to accomplish:

Function Remove-Parent {
  param(
    [string]$Path, 
    [string]$Parent) 
  $len = $Parent.length
  $Path.SubString($Len)
}

The following is not the way you likely would use it but does demonstrate that the function returns the expected results:

@'
D:\this\is\where\it\starts
D:\this\is\where\it\starts\dir1\file1
D:\this\is\where\it\starts\dir1\file2
D:\this\is\where\it\starts\dir1\file3
D:\this\is\where\it\starts\dir1\dir2\file1
'@ -split "`n" | ForEach-Object { Remove-Parent $_ 'D:\This\Is'  }

# Outputs
\where\it\starts
\where\it\starts\dir1\file1
\where\it\starts\dir1\file2
\where\it\starts\dir1\file3
\where\it\starts\dir1\dir2\file1

Just call the function with the current path ($_.fullname) and the "prefix" you are expecting to remove.

The function above is doing this strictly on 'length' but you could easily adapt it to match the actual string with either a string replace or a regex replace.

Function Remove-Parent {
  param(
    [string]$Path, 
    [string]$Parent
  )
  $remove = [regex]::Escape($Parent)
  $Path -replace "^$remove"
}

The output was the same as above.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.