在 PowerShell 中连接字符串变量

concatenating String variables in PowerShell

提问人:Juerg Meister 提问时间:10/4/2023 最后编辑:mklement0Juerg Meister 更新时间:10/4/2023 访问量:50

问:

我有以下PowerShell脚本:

$Folder = Get-Location
$FileName = Get-Item *.csv | Select-Object Name
$FullPath = Get-Item *.csv | Select-Object FullName
$Archive = $Folder, "Archive" -join '\'
$FileArchive = $Archive, $FileName -join '\'

输出如下:

Path
C:\Test

Name : Orders_1408230845.csv

FullName : C:\Test\Orders_1408230845.csv

C:\Test\Archive
C:\Test\Archive\

问题是,对于我的期望,但它只显示(没有文件名)。 为什么文件名没有添加到?$FileArchiveC:\Test\Archive\Orders_1408230845.csvC:\Test\Archive\$Archive

我还尝试了其他字符串连接,如运算符或方法,但无济于事。+Concat

PowerShell 字符串串联

评论

2赞 Jonathan Dodds 10/4/2023
我希望这将表明这不是一个.$FileName.GetType()$FileNamestring
3赞 MisterSmith 10/4/2023
Get-Item *.csv可以返回许多文件,因此您需要使用 For-EachObject 循环处理每个文件 - 简短语法如下所示: . 将是从 传递的当前对象。还可以使用此语法进行串联| % { $_.FullName }$_Get-Item$FileArchive = "${$Folder}\Archive\${$_.Name}"
0赞 Olaf 10/4/2023
你到底想做什么?如果你想建立一个正确的路径,你可以使用Join-Path而不是古怪的弦乐杂技。;-)
2赞 lit 10/4/2023
Juerg,请尝试以下命令。它将为每个 .csv 文件生成一个完全合格的路径。 无需字符串连接。如果需要,是要使用的命令。目录中是否有多个 .csv 文件?Get-Item -Path '*.csv' | Select-Object -ExpandProperty FullNameJoin-Path
0赞 mklement0 10/4/2023
我已经为这篇文章做了,但请以后正确格式化您的帖子

答:

2赞 mklement0 10/4/2023 #1

默认情况下,Select-Object () 返回具有请求属性的 [pscustomobject] 实例 - 即使只请求单个属性也是如此。select

您感兴趣的只是属性,可以使用 -ExpandProperty 参数而不是(可能是位置隐含的)参数来获取
这些值:
-Property

$FileName = Get-Item *.csv | Select-Object -ExpandProperty Name
$FullPath = Get-Item *.csv | Select-Object -ExpandProperty FullName

由于您无论如何都在内存中收集结果,因此更简单的替代方法是使用属性访问,由于成员访问枚举,如果返回多个文件,它甚至可以工作:

$FileName = (Get-Item *.csv).Name
$FullPath = (Get-Item *.csv).FullName

注意:

  • 正如 Mister Smith 所指出的,鉴于您的调用可能会返回多个文件,因此在循环中处理结果会更安全。Get-Item

  • 请考虑使用 Join-Path cmdlet,而不是使用 。-join '\'


至于为什么文件名丢失

$Archive, $FileName -join '\'

  • 如上所述,不是字符串,而是具有属性的实例。$FileName[pscustomobject].Name

  • 由于一个长期存在的错误 - 请参阅 GitHub 问题 #6163 - 此类实例在上下文中字符串化为空字符串,这就是您所看到的。

一个简化的例子;该错误存在于 Windows PowerShell 以及 PowerShell (Core) 中,最高可达 v7.3.7(截至撰写本文时):

# !! -> 'C:\temp\', i.e the custom object stringified to the empty string. 
'C:\temp', [pscustomobject] @{ Name = 'foo.csv' } -join '\'

(奇怪的是,没有表现出这个问题 - 你会得到通常的、类似哈希表的字符串化。Join-Path 'C:\temp' ([pscustomobject] @{ Name = 'foo.csv' })