不同长度的数组到一个 CSV

Bob*_*son 3 arrays powershell export-to-csv

如果您有多个不同长度的数组,如何将它们导出到 powershell 中的单个 csv 中?

\n
Array1 = 1,2,3 \nArray2 = Bob,smithy,Alex,Jeremy \nArray3 = yes,no\n
Run Code Online (Sandbox Code Playgroud)\n

输出 CSV

\n
\n号码名称有效\n\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2 \x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94\xe2\x80 \x94\xe2\x80\x94\xe2\x80\x94\xe2\x80\x94 \n1 鲍勃 是 \n2 史密斯 没有 \n3 亚历克斯\n 杰里米
\n

基本上每个数组都位于其自己的标题列中。

\n

尝试过类似的行

\n
Array1 | Select-Object Number | export-csv -Path C:\\Path\n
Run Code Online (Sandbox Code Playgroud)\n

这适用于单一数组到单一 csv 文件

\n

但如果我尝试

\n
Array1, Array2, Array3 | Select-Object Number, Name, Valid | export-csv -Path C:\\Path\n
Run Code Online (Sandbox Code Playgroud)\n

我只得到标题名称,列中没有值

\n

San*_*zon 7

一种方法是使用for循环

$Array1 = 1, 2, 3
$Array2 = 'Joe Bloggs', 'John Doe', 'Jane Doe'
$Array3 = 'Yes', 'No'

$export = for($i = 0; $i -lt [Linq.Enumerable]::Max([int[]] ($Array1.Count, $Array2.Count, $Array3.Count)); $i++) {
    [pscustomobject]@{
        Number = $Array1[$i]
        Name   = $Array2[$i]
        Valid  = $Array3[$i]
    }
}
$export | Export-Csv path\to\csv.csv -NoTypeInformation
Run Code Online (Sandbox Code Playgroud)

另一个使用function的示例,逻辑或多或少相同,只是涉及更多开销,因为该函数可以处理来自管道的无限数量的数组。

function Join-Array {
    [CmdletBinding()]
    param(
        [parameter(ValueFromPipeline, Mandatory)]
        [object[]] $InputObject,

        [parameter(Mandatory, Position = 0)]
        [string[]] $Columns
    )

    begin {
        $inputDict = [ordered]@{}
        $index = 0
    }
    process {
        try {
            if ($MyInvocation.ExpectingInput) {
                return $inputDict.Add($Columns[$index++], $InputObject)

            }

            foreach ($item in $InputObject) {
                $inputDict.Add($Columns[$index++], $item)
            }
        }
        catch {
            if ($_.Exception.InnerException -is [ArgumentNullException]) {
                $errorRecord = [Management.Automation.ErrorRecord]::new(
                    [Exception] 'Different count between input arrays and Columns.',
                    'InputArrayLengthMismatch',
                    [Management.Automation.ErrorCategory]::InvalidOperation,
                    $InputObject
                )
                $PSCmdlet.ThrowTerminatingError($errorRecord)
            }
            $PSCmdlet.ThrowTerminatingError($_)
        }
    }
    end {
        foreach ($pair in $inputDict.GetEnumerator()) {
            $count = $pair.Value.Count
            if ($count -gt $max) {
                $max = $count
            }
        }

        for ($i = 0; $i -lt $max; $i++) {
            $out = [ordered]@{}
            foreach ($column in $inputDict.PSBase.Keys) {
                $out[$column] = $inputDict[$column][$i]
            }
            [pscustomobject] $out
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用起来非常简单,要连接/压缩的数组可以通过管道传递,并按位置定义所需的列名称:

$Array1 = 1, 2, 3
$Array2 = 'Joe Bloggs', 'John Doe', 'Jane Doe'
$Array3 = 'Yes', 'No'
$Array4 = 'hello', 'world', 123, 456

$Array1, $Array2, $Array3, $Array4 | Join-Array Number, Name, Valid, Test |
    Export-Csv path\to\csv.csv -NoTypeInformation
Run Code Online (Sandbox Code Playgroud)

  • 我不知道你可以用这种方式将“for”循环分配给变量,尽管事后看来,如果每次迭代只在管道上留下一个值,这是有意义的。我将来肯定会更多地使用这种技术。 (2认同)