提问人:Juerg Meister 提问时间:10/4/2023 最后编辑:mklement0Juerg Meister 更新时间:10/4/2023 访问量:50
在 PowerShell 中连接字符串变量
concatenating String variables in PowerShell
问:
我有以下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\
问题是,对于我的期望,但它只显示(没有文件名)。
为什么文件名没有添加到?$FileArchive
C:\Test\Archive\Orders_1408230845.csv
C:\Test\Archive\
$Archive
我还尝试了其他字符串连接,如运算符或方法,但无济于事。+
Concat
答:
默认情况下,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' })
评论
$FileName.GetType()
$FileName
string
Get-Item *.csv
可以返回许多文件,因此您需要使用 For-EachObject 循环处理每个文件 - 简短语法如下所示: . 将是从 传递的当前对象。还可以使用此语法进行串联| % { $_.FullName }
$_
Get-Item
$FileArchive = "${$Folder}\Archive\${$_.Name}"
Get-Item -Path '*.csv' | Select-Object -ExpandProperty FullName
Join-Path