【问题标题】:How to Export-Csv with variables?如何使用变量导出 Csv?
【发布时间】:2017-07-27 14:54:50
【问题描述】:

我正在尝试使用 PowerShell 将 8 个变量写入 CSV 文件,但最终结果为 ,,,,,,, 而不是 var1,var2,var3,var4,var5,var6,var7,var8

我的代码如下:

$newRow = "{0},{1},{2},{3},{4},{5},{6},{7}" -f $var1,$var2,$var3,$var4,$var5,$var6,$var7,$var8
$newRow = $newRow -Replace "`t|`n|`r",""
$newRow = $newRow -Replace " ;|; ",";"
$newRow += "`n"
$newRow | Export-Csv -Path $file -Append -noType -Force

如果没有-Force,我会收到以下错误消息:

Export-Csv:无法将 CSV 内容附加到以下文件:C:\result.txt。这
附加对象没有对应于以下列的属性:
变量 1。要继续使用不匹配的属性,请添加 -Force 参数,然后
重试该命令。
在 C:\Test.ps1:72 char:12
+ $新行 |导出-Csv -Path $file -Append -noType
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo : InvalidData: (var1:String) [Export-Csv], InvalidOperationException
     + FullyQualifiedErrorId : CannotAppendCsvWithMismatchedPropertyNames,Microsoft.PowerShell.Commands.ExportCsvCommand

编辑:

脚本:

$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = "powershell.exe"
$startInfo.Arguments = 'C:\zabbix\script\zabbix_vbr_job.ps1 "Discovery"'

$startInfo.RedirectStandardOutput = $true
$startInfo.UseShellExecute = $false
$startInfo.CreateNoWindow = $false
#$startInfo.Username = "DOMAIN\Username"
#$startInfo.Password = $password

$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
$process.Start() | Out-Null
$discoveryJson = $process.StandardOutput.ReadToEnd()
$process.WaitForExit()
cls

$discovery = $discoveryJson | ConvertFrom-Json
$file = "C:\zabbix\script\result.txt"

function RunScript ($param, $id)
{
    $startInfo = New-Object System.Diagnostics.ProcessStartInfo
    $startInfo.FileName = "powershell.exe"
    $startInfo.Arguments = "C:\zabbix\script\zabbix_vbr_job.ps1 '$param' '$id'"

    $startInfo.RedirectStandardOutput = $true
    $startInfo.UseShellExecute = $false
    $startInfo.CreateNoWindow = $false

    $process = New-Object System.Diagnostics.Process
    $process.StartInfo = $startInfo
    $process.Start() | Out-Null
    $output = $process.StandardOutput.ReadToEnd()
    $process.WaitForExit()

    return $output
}

$fileContent = Import-csv $file

$NewCSVObject = @()
foreach($obj in $discovery.data)
{
    $index = [array]::indexof($discovery.data, $obj)
    Write-Host $index "/" $discovery.data.count
    #Write-Host (RunScript "Result" $obj.JOBID )
    $Result = RunScript "Result" $obj.JOBID
    #Write-Host $Result
    $RunStatus = RunScript "RunStatus" $obj.JOBID
    #Write-Host $RunStatus
    $IncludedSize = RunScript "IncludedSize" $obj.JOBID
    #Write-Host $IncludedSize
    $ExcludedSize = RunScript "ExcludedSize" $obj.JOBID
    #Write-Host $ExcludedSize
    $VmCount = RunScript "VmCount" $obj.JOBID
    #Write-Host $VmCount
    $Type = RunScript "Type" $obj.JOBID
    #Write-Host $Type
    $RunningJob = "RunningJob"#RunScript "RunningJob" $obj.JOBID
    #Write-Host $RunningJob

    #$newRow = New-Object PsObject -Property @{ JobID = $obj.JOBID ; Result = $Result ; RunStatus = $RunStatus ; IncludedSize = $IncludedSize ; ExcludedSize = $ExcludedSize ; VmCount = $VmCount ; Type = $Type ; RunningJob = $RunningJob }
    $newRow = "{0},{1},{2},{3},{4},{5},{6},{7}" -f $obj.JOBID,$Result,$RunStatus,$IncludedSize,$ExcludedSize,$VmCount,$Type,$RunningJob
    $newRow = $newRow -Replace "`t|`n|`r",""
    $newRow = $newRow -Replace " ;|; ",";"
    $newRow += "`n"
    #$newRow | Out-File $file
    #[io.file]::WriteAllText("C:\zabbix\script\test.txt",$newRow)
    Write-Host $newRow
    $newRow | Export-Csv -Path $file -Append -noType
    break
}
#cls
Write-Host $fileContent

CSV 标题:

JobID,Result,RunStatus,IncludedSize,ExcludedSize,VmCount,Type,RunningJob

【问题讨论】:

  • 能否请您完整发布脚本,以便我们查看$file 中包含的内容以及$vars 的值?了解$file的文件中已经存在什么(如果有的话)也可能会有所帮助
  • 我刚刚编辑了 OP @Bassie
  • 请参阅链接了解如何创建最小、完整且可验证的示例:stackoverflow.com/help/mcve。例如,我不知道$discovery 的值是什么,也不知道zabbix_vbr_job.ps1 中包含什么。也许一个好的起点是检查$obj$result 等在调用Export-Csv 时是否实际保持预期值。由于我自己无法检查,我不知道是否可以预期空白的,,,,,,, 输出
  • 变量保存正确的数据,我可以 Out-File 就好了,但是当我尝试 Export-CSV 时,我只得到 ,,,,,,,
  • 您的脚本正在完成 Export-Csv 为您完成的所有工作,用逗号分隔值,在末尾添加换行符等。但是您的脚本没有为 Export-csv 提供那种它需要的对象。它需要一个具有名为 var1、var2、var3 等属性的对象,假设现有的 csv 文件在其标题中具有这些变量名称。

标签: powershell csv


【解决方案1】:

如果您还是手动构建 CSV 行,那么使用 Export-Csv 毫无意义。

要么改变

$newRow | Export-Csv -Path $file -Append -noType -Force

进入

$newRow | Add-Content $file

或像这样构建$newRow

$newRow = New-Object -Type PSObject -Property @{
  'JobID'        = $var1
  'Result'       = $var2
  'RunStatus'    = $var3
  'IncludedSize' = $var4
  'ExcludedSize' = $var5
  'VmCount'      = $var6
  'Type'         = $var7
  'RunningJob'   = $var8
}

问题就会消失。


这种行为的原因是Export-Csv 用于将对象转换为其属性的表格字符串表示形式。本质上,一个对象

@{
  propertyA: 'foo'
  propertyB: 23
}

变成

属性A,属性B
"foo","23"

如果您已经在构建字符串,则生成的(字符串)对象只有一个属性 (Length),它与现有 CSV 中的任何属性都不匹配。因此,如果没有-Force,您会遇到错误。即使您使用-Force,写入 CSV 的属性也是从现有 CSV 中的第一项确定的。该集合中不存在的属性会从输出中省略,该集合中不存在于对象中的属性将填充为空值。

【讨论】:

  • 做到了,我使用了 New-Object 方法,现在就像一个魅力:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多