这是PowerShell的TrimStart中的错误吗?

时间:2017-10-03 19:36:24

标签: powershell

如果我对此感到沮丧,请原谅我。但是,这就是为什么我讨厌尝试使用像PowerShell这样的脚本语言来做任何远程复杂的事情。这是一场永无止境的无法预测的战斗。

所以,这是:

PS C:\WINDOWS\system32> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      15063  632 

PS C:\WINDOWS\system32> $testpath = "\\a-server-unc\home\auser\Outlook Data\archive1 - Copy.pst"

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent)
\\a-server-unc\home\auser\Outlook Data #Ok - Looks good

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent).TrimStart("\\a-server-unc")
home\auser\Outlook Data   # Where did my slash go?

PS C:\WINDOWS\system32> $(Split-path -path $testpath -parent).TrimStart("\\a-server-unc\home")
Outlook Data  # Wait - What the...

PS C:\WINDOWS\system32> $testpath
\\a-server-unc\home\auser\Outlook Data\archive1 - Copy.pst # Yep - I'm not insane. Powershell is eating my characters.

PS C:\WINDOWS\system32> $testpath = "\\a-server-unc\home\aloser\Outlook Data\archive1 - Copy.pst"  #Let's try changing the string a little

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent).TrimStart("\\a-server-unc\home")
loser\Outlook Data   # I must be insane

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent).TrimStart("`\`\a-server-unc`\home") #Certainly escaping the slashes will fix this?
loser\Outlook Data   # Nope, more hours wasted on unpredictable behavior

现在显然有一些奇怪的,#34;完全正常"这里的行为,但我有点厌倦了Powershell吃掉我的琴弦。

这里的神奇药水是什么?

2 个答案:

答案 0 :(得分:2)

这是预期的行为。

根据文件

String.TrimStart方法(Char())

从当前String对象中删除数组中指定的一组字符的所有前导事件。 - source

要修剪连续的字符串,可以使用-replace using regex

"\a-server-unc\home\user\a-server-unc\Outlook Data\archive1" -replace "^\\a-server-unc\\",''

输出结果为

  

home \ user \ a-server-unc \ Outlook Data \ archive1

关键字符包括^表示事件发生在行开始之后而不是任何地方(这就是为什么我的替换的第二次出现的原因。)

如果你想避免使用正则表达式,你需要这样的东西:

function TrimStart([String]$InputObject,[String]$Value){
    if ($InputObject.StartsWith($Value)) {
        return $InputObject.Substring($value.Length,$InputObject.Length - $value.Length)
    }
    else{
        return $InputObject
    }
}

这是两者在行动中的区别。 $ ConceptString ='这是一个很长的字符串,也恰好是一个完整的句子!!!'

write-host $ConceptString.TrimStart('This is a very long string') -ForegroundColor Cyan
#Output: ppens to be a complete sentence !!!
Write-host $(TrimStart $ConceptString -Value 'This is a very long string')  -ForegroundColor Green
#output: that also happens to be a complete sentence !!!

答案 1 :(得分:1)

请在此处查看TrimStart()文档:https://msdn.microsoft.com/en-us/library/system.string.trimstart.aspx

特别要注意TrimStart()将字符数组作为输入,而不是字符串(正如您所期待的那样):

public string TrimStart(
    params char[] trimChars
)

所以TrimStart()删除字符,而不是整个字符串。

例如,参见输出:

$testpath = "hhhhhhhhhhhhhhelloooooooo".TrimStart("h")

输出:

  

elloooooooo。

解决方案是使用Replace()函数。

这样做的一种方式:

$testpath = "\\a-server-unc\home\auser\Outlook Data\archive1 - Copy.pst"
$basepath = "\\a-server-unc\"
[regex]$pattern = [regex]::escape($basepath)
# pattern is regex version of string you want to replace
# .replace("string to replace", "replacing string", numberOfReplacements)
# i.e. only replace the 1st instance
$newPath = $pattern.replace($testpath, [string]::Empty, 1)

$newPath的输出:

  

home \ auser \ Outlook Data \ archive1 - Copy.pst