【pwsh】 Write-Output、数组合并与单行文本

1. 问题

在powershell中,有时,我们会需要向之前的一个数组中添加更多的元素,如果是添加单个对象,只需要使用操作符+=。但我们要合并两个多对象的数组时,需要通过遍历来将一个数组添加到另一个数组之中,这一过程是相当繁琐的。当然也可以使用ListArrayList对象中的AddRange方法,但也需要进行类型转化。有没有更简洁的方式来合并两个甚至更多的数组呢?

2. 解决方案

powershell是直接输出对象,遍历对象数组(可关闭)。在数组的处理上,如果要使用到索引,建议使用强类型进行约束。另一方面,如果要合并数组,不必手动遍历,直接使用$(;)将多行输出结果合并赋值即可。

powershell中可以将各种表达式的输出结果可以使用用$()&{}汇总赋值给某一变量。Write-Output(别名echo)的帮助文档表明1,其作用是将指定对象输出到控制台或管道中,默认遍历数组。当然也可以启用-NoEnumerate开关参数来将整个数组传递给管道。该命令使用的是Cmdlet.WriteObject(object sendToPipeline, bool enumerateCollection)2方法。

创建数组主要使用@(),。使用$(;)可以实现数组的合并,还可以搭配Write-Output选择是否遍历数组。下面代码中可以看出,虽然输出结果看似一致,但其结构是不一样的。因为无论数组嵌套了多少层,最终都会被递归为深度为一的数组。

$arr1 = [pscustomobject]@{
    
     FullName = "C:\temp"; Name = "temp" }
# FullName Name
# -------- ----
# C:\temp  temp
$arr2 = 1..3 | % {
    
     [pscustomobject]@{
    
     FullName = "C:\temp\file_$_"} }
# FullName
# --------
# C:\temp\file_1
# C:\temp\file_2
# C:\temp\file_3

$arr3 = @($arr1, $arr2) # 创建一个长度为2的数组
$arr3 = $arr1, $arr2    # 省略后的数组生成方式
$arr3 = $(echo $arr1 -NoEnumerate; echo $arr2 -NoEnumerate)
# 上式结果与前面的数组生成、使用+=操作符结果相一致

$arr4 = $($arr1; $arr2)
# 将echo枚举结果合并,赋值给新变量
# 该结果长度为4,$arr1 和 $arr2 都被 echo 所遍历
# 类似动态规划枚举节点树

另一方面,由于WriteObject()会将长度为1的数组遍历为内部的对象,因此在数组经过管道或函数生成数组类型的值时,若想保持数组的完整性,需要在赋值时使用强类型进行约束。例如Get-Content等大多数命令结果都为数组,遇到单行文本时,使用索引取值就会出问题。不过管道foreach并不会遇到这样的问题,可以放心使用。

$arr5 = @(1) | %{
    
     "line 1" }; $arr5.pstypenames
# System.String
# System.Object

# 使用强类型约束,[array]可以换为[<classType>[]]的形式
$arr5 = [array](@(1) | %{
    
     "line 1" })
[array]$arr5 = (@(1) | %{
    
     "line 1" })

3. 参考


  1. Get-Help Write-Output ↩︎

  2. Cmdlet.WriteObject Method ↩︎

猜你喜欢

转载自blog.csdn.net/qq_41755979/article/details/105741385