【问题标题】:Having trouble using the export-csv使用 export-csv 时遇到问题
【发布时间】:2014-03-29 08:59:31
【问题描述】:

我有 3 个 csv 文件,它们都只有 1 列长。我已经尝试了很多东西将它们全部放在一个 csv 文件中,但我无法让它工作。当我输出它时,它最终都在一列中,这就是我到目前为止所做的

#Putting Csv files to Array    
$CSV1 = @(gc $EmailPathCsv)
$CSV2 = @(gc $UserLPathCsv)
$CSV3 = @(gc $EmailPathCsv)

#
for ($i=0; $i -lt $CSV1.Count; $i++) 
    {
    $CSV4 += $CSV1[$i] + "," + $CSV2[$i] + "," + $CSV3[$i] + " "
    }

$csv4 | out-file -append $MergedCsvExport

【问题讨论】:

  • 因此,例如...您有 3 个文件,其中包含 10 个条目和一个标题(我假设还有更多)。您是要制作 1 个包含 1 个标题和 30 个条目的文件,还是制作 3 个标题和 10 行各 3 列的文件?
  • 没关系,我只是重新阅读了您的代码。试试这个......在你的 For 循环之前,将 $CSV4 创建为一个空数组,如 $CSV4 = @() 然后重新运行它。我还没有测试过,但我打赌它会为你做的。

标签: powershell csv


【解决方案1】:

您的循环正在将所有内容添加到 $CSV4 中,每次循环 $CSV4 都会变得越来越长。

然后你打印一次。这就是为什么你会得到一条很长的线路。尝试每次循环打印一次,每次都覆盖 $CSV4:

#Putting Csv files to Array    
$CSV1 = @(gc $EmailPathCsv)
$CSV2 = @(gc $UserLPathCsv)
$CSV3 = @(gc $EmailPathCsv)

#
for ($i=0; $i -lt $CSV1.Count; $i++) 
    {
    $CSV4 = $CSV1[$i] + "," + $CSV2[$i] + "," + $CSV3[$i] + " "
    out-file -InputObject $csv4 -Append -FilePath $MergedCsvExport
    }

【讨论】:

  • 对于您要完成的工作,您需要做很多额外的工作。将整个 For 循环内部更改为:$CSV1[$i] + "," + $CSV2[$i] + "," + $CSV3[$i]|out-file $MergedCsvExport -Append
  • 您的建议更好,但我试图对他们的代码进行最小的更改,这可能会起作用,因此提问者看起来仍然很熟悉。我试图完全重写它,我想出了这个:stackoverflow.com/a/22725084/478656 ;)
【解决方案2】:

我会为此使用格式字符串。

$CSV1 = @(gc $EmailPathCsv)
$CSV2 = @(gc $UserLPathCsv)
$CSV3 = @(gc $EmailPathCsv)

for ($i=0; $i -lt $CSV1.Count; $i++) 
 {
  '"{0}","{1}","{2}"' -f $CSV1[$i],$CSV2[$i],$CSV3[$i] |
   add-content $MergedCsvExport
 }

【讨论】:

    【解决方案3】:

    作为一个更有趣的答案:

    $CSV1 = 1,2,3,4
    $CSV2 = 10,11,12,13
    $CSV3 = 'a','b','c','d'
    
    $c = gv -Name CSV* | select -expand name | sort
    
    (gv -Va $c[0])|%{$r=0}{@($c|%{(gv -Va $_)[$r]}) -join ',';$r++}
    

    样本输出:

    1, 10, a
    2, 11, b
    3, 12, c
    4, 13, d
    

    您可以将|Out-File "merged-data.csv" 放在末尾以保存到文件中。

    它也适用于更多列,只需添加更多名为 $CSV{something} 的数组。

    编辑:我想知道 Get-Variable 的输出是按可预测的顺序还是未指定的?如果您不介意列顺序是否会改变,它会折叠为:

    $CSV1 = 1,2,3,4
    $CSV2 = 10,11,12,13
    $CSV3 = 'a','b','c','d'
    
    (gv CSV*)[0].Value|%{$r=0}{@((gv CSV*)|%{(gv -Va $_.Name)[$r]}) -join ',';$r++}
    

    再次编辑:好吧,如果有人注意到并且好奇并且有时间,我已经扩展了它并解释了它在做什么:

    # Search the local variable scope for variables named CSV*
    # This will find $CSV1, $CSV2, etc.
    # This means the number of columns
    # isn't fixed, you can easily add more.
    # Take their names, sort them. 
    # Result: an array of strings "CSV1", "CSV2", ...
    # for however many variables there are
    $columnVariables = Get-Variable -Name "CSV*" | Select-Object -Expand Name | Sort-Object
    
    # NB. if you remove $CSV3= from your code, it is
    # still in memory from previous run. To remove
    # it, use `Remove-Variable "CSV3"
    
    # In pseudo-code, what the next part does is
    # for row in range(data):
    #    @(CSV1[row], CSV2[row], ... CSVn[row]) -join ','
    
    # The outer loop over the number of columns
    # is done by piping something of the right length
    # into a foreach loop, but ignoring the content.
    # So get the first column array content:
    $firstColumn = (Get-Variable $columnVariables[0]).Value
    
    # and pipe it into a loop.
    # The loop uses ForEach {setup} {loop} pattern 
    # to setup a row-counter before the loop body
    $firstColumn | ForEach { $row=0 } {
    
        # Now we know the row we are on, we can get
        # $CSV1[row], $CSV2[row], ...
        # Take the column variable array "CSV1", "CSV2", ..
        # Loop over them
        $rowContent = $columnVariables | ForEach {
    
            # $_ a string of the name, e.g. "CSV1"
            # Use Get-Variable to convert it
            # into the variable $CSV1
            # with -ValueOnly to get the array itself
            # rather than details about the variable
            $columnVar = Get-Variable -ValueOnly $_
    
            # $columVar is now one of the $CSVn variables
            # so it contains, e.g. 1,2,3,4
            # Index into that for the current row
            # to get one item, e.g. 3
            # Output it into the pipeline
            ($columnVar)[$row]
    
            } # This is the end of the inner loop
              # The pipeline now contains the column
              # values/content making up a single row
              # 1
              # 10
              # 'a'
    
        # Back in the outer row loop, Take the row
        # content and make it a comma separated string
        # e.g. "1,10,a"
        # Output this into the pipeline
        @($rowContent) -join ','
    
        # Increment the row counter
        $row++
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-01
      • 2018-05-01
      • 2016-04-06
      • 2021-11-27
      • 2018-01-06
      • 2011-06-28
      • 2020-09-16
      • 2011-04-10
      • 1970-01-01
      相关资源
      最近更新 更多