Powershell在单个命令行上组合变量表达式

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (168)

我试图了解Powershell如何在命令行上处理变量表达式(例如,作为cmdlet的参数)。我似乎无法准确理解它如何解析涉及多个变量(和/或变量属性)的表达式。以下是基于以下预定义变量的示例:

$a = 'abc'
$b = 'def'
$f = Get-ChildItem .\Test.txt   # assuming such a file exists in the current directory

例1:

echo $a$b

输出: abcdef

例2:

echo $a\$b

输出: abc\def

例3:

echo $f.BaseName

输出: Test

例4:

echo $a\$f.BaseName

输出: abc\C:\Test.txt.BaseName

基本上,我不明白为什么我可以组合两个变量(例1和2),我可以使用变量属性(例3),但我不能将变量与其他变量属性组合(例4)。我尝试了各种转义序列(使用反引号)无济于事。

我意识到我可以使用$()样式表达式完成此操作,例如:

echo $($a + '\' + $f.BaseName)

我只是不明白为什么另一种形式(例子4)无效 - 在我看来它更清晰。

提问于
用户回答回答于

tl;博士:

最安全的选择是始终使用显式双引号复合参数,使平常的字符串扩展(插值)的规则适用

应用于您的示例(我正在使用Write-Output,因为这echo是PowerShell中的别名):

Write-Output "$a$b" # example 1
Write-Output "$a\$b" # example 2
Write-Output "$a\$($f.BaseName)" # example 4 - note the required $(...)

唯一的例外是示例3,因为您没有处理复合参数,而是处理单个表达式

Write-Output $f.BaseName # example 3: OK without quoting
Write-Output "$($f.BaseName)" # equivalent with double-quoting

PowerShell 主要将复合参数视为双引号(即可扩展)字符串,但最终有太多例外情况可供使用

这个GitHub问题总结了所有令人惊讶的行为。

至于你的具体问题

我无法将变量与其他变量属性组合在一起(例4)。

实际上,echo $a\$f.BaseName复合令牌隐含地视为包含在其中的情况"...",正是因为你需要将其括$f.BaseName起来$(...),因为这就是字符串扩展规则所需要的。

echo $a\$($f.BaseName)

我意识到我可以使用$()样式表达式完成此操作,例如: echo $($a + '\' + $f.BaseName)

实际上,(...)在这种情况下简单使用它会更好,更有效,因为你想要评估的是一个单独的表达式

echo ($a + '\' + $f.BaseName)
用户回答回答于

$()和之间有一些细微的差别()。我会说在你的例子中,在大多数情况下,你应该使用()

$()可以在需要更复杂的东西或不能使用的表达式时使用()。请注意,输出$()基本上就像输出管道一样,所以有些事情你可能不会发生。例如,看看这两个的输出:

(1..10 -as [string[]]).GetType()
$(1..10 -as [string[]]).GetType()

在第二种情况下,[string[]]阵列已展开,然后重新分组为PowerShell的默认数组输出类型[object[]]

扫码关注云+社区

领取腾讯云代金券