在-replace表达式中执行字符串操作

时间:2018-03-14 12:28:06

标签: powershell

我试图使用String.Substring()将来自某个位置的每个字符串替换为其子字符串。我很难找到合适的语法。

$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

我指的是以下表达式

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

第4个字符的子字符串不能替换路径的全名。 有问题的路径超过4个字符。

运行脚本时输出对于全名只是空的。 有人可以帮我解决语法

修改 未改变的字符串列表(如Get-ChildItem recurses)将是

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

$_.FullName因此将采用上面列出的每个字符串的值。 给定输入,如 D:\ this \是 D:\ this \是\ where ,然后我计算此输入的长度(包括分隔符) \)然后将$_.FullName替换为从第n个位置开始的子字符串,其中 n 是输入的长度。

如果输入为D:\ this \ is,则长度为10。 预期输出

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

2 个答案:

答案 0 :(得分:1)

如果要从字符串中删除特定前缀,可以这样做:

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

要删除给定长度的前缀,您可以执行以下操作:

$len = 4
...
$_.FullName -replace "^.{$len}"

答案 1 :(得分:0)

遇到麻烦时,请简化:

此功能将完成您​​显然要完成的任务:

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

以下不是您可能使用它的方式,但确实证明该函数返回了预期的结果:

@'
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

只需使用当前路径($ _。fullname)和您希望删除的“前缀”调用该函数。

上面的函数严格按“长度”执行此操作,但您可以轻松地调整它以匹配实际字符串与字符串替换或正则表达式替换。

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

输出与上述相同。