使用 powershell 在 CSV 中追加行

append rows in CSV using powershell

我有一段代码如下。

$month = Get-Date -Format "yyyy_MM"
$csv_location = "C:\brivo\csv\" + $month + ".csv"
if (!(Test-Path $csv_location))
{
    $newcsv = {} | Select "Time","Name","Surname","Email","Telephone","Company","Department","Address","Postcode","City","State","Country" | Export-Csv $csv_location -NoTypeInformation
}

ForEach($line in $lines){
    Try
    {
        $line = $line.Trim()
        $file = "C:\brivo\json\" + $line
        $data = Get-Content $file | ConvertFrom-Json
    
        $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm"

        $userline = $timestamp,$data.name,$data.surname,$data.email,$data.telephone,$data.company_name,$data.department,$data.address,$data.postcode,$data.city,$data.state,$data.country
        $userline | out-file $csv_location -Append
    }
    Catch [Exception]
    {
        Write-Host $_.Exception | format-list -force
    }
}

如果 headers 不存在,第一部分是创建 csv 文件。在第二部分 $lines 是像 123.json, 456.json... 和所有那些 json 文件有如下内容。

{
    "name": "kamal",
    "sur_name": "wewetwe",
    "email": "asdasd@gmail.com",
    "telephone": "311234544567",
    "company_name": "",
    "department": "",
    "address": "qwe",
    "postcode": "1234 ad",
    "city": "qwe",
    "state": "GR",
    "country": "NL"
}

我想要的是将所有这些 json 数据附加到 csv 文件。我已经像上面那样尝试过,但它会在第一列本身添加数据。

**这是一些例子**

 #add your json files on temp dir
    $a= Get-ChildItem C:\Temp\PatchingServer*
    foreach($g in $a){
        $j=gc $g
        $f=$j| ConvertFrom-Json    
        $obj=New-Object PSobject
        $obj | Add-Member Noteproperty "Port" $f.Port       
        $obj | Add-Member Noteproperty "ApplicationName" $f.ApplicationName
        $obj | Add-Member Noteproperty "MaintenanceWindow" $f.MaintenanceWindow
        $obj | Add-Member Noteproperty "BusinessUnit" $f.BusinessUnit
        $obj | Add-Member Noteproperty "AppOwner"  $f.AppOwner
        $obj | Add-Member Noteproperty "AppID"    $f.AppID
        $obj | Add-Member Noteproperty "Location" $f.Location
        $obj | export-csv C:\Temp\Patching.csv  -NoTypeInformation -Append
    }
  • 不要尝试使用 Export-Csv 在没有数据 的情况下初始化 CSV 文件 ,因为这样是行不通的:

    • Select-Object 创建的具有 $null 属性 值的虚拟 object 结果不仅在 header 行,但总是在 数据行中 表示 $null 值,最终为空字符串;换句话说,您将获得如下所示的数据行:,,,,,,,,,,,

    • 相反,请确保 object 的 属性 表示您传递的数据行 Export-Csv 以所需的 CSV 列命名

  • 不要尝试将数据行构造为 数组 值以保存到 CSV 文件 作为纯文本;[1],为每个数据行构造一个[pscustomobject]Export-Csv自动转换为一个数据行,其中 属性 名称用作列名称(正如您尝试使用 header 行)。

    • 如下面的代码所示,您可以在每次迭代中构建一个 object 并将其通过管道传输到 single Export-Csv 调用以提高效率。
      • 使用-Encoding参数根据需要控制输出字符编码;值得注意的是,在 Windows PowerShell 中,默认编码是 ASCII(!)。
    • -Append 仍在该单个调用中使用,因为看起来您想追加到预先存在的目标文件(如果存在)。
    • 重要
      • 发送到Export-Csvfirstobject根据its[=75=锁定列列表及其名称] 特性;随后的 object 应该具有相同的属性集(或有意义的子集)。
      • 类似地,当使用 -Append 附加到预先存在的 CSV 文件时,要附加的 object 必须与现有列匹配,尽管您可以使用 -Force 覆盖此要求。
$month = Get-Date -Format "yyyy_MM"
$csv_location = "C:\brivo\csv\" + $month + ".csv"

# $lines is assumed to be an array of your input JSON file names.
$lines | ForEach-Object {
    Try
    {
        $file = "C:\brivo\json\" + $_.Trim()
        $data = Get-Content -ErrorAction Stop -Raw $file |
                  ConvertFrom-Json -ErrorAction Stop
    
        # Construct and output an object with the desired values and the
        # properties named for the desired CSV columns.
        [pscustomobject] @{
          Time = Get-Date -Format 'yyyy-MM-dd HH:mm'
          Name = $data.name
          Surname = $data.surname
          Email = $data.email
          Telephone = $data.telephone
          Company = $data.company_name
          Department = $data.department
          Address = $data.address
          Postcode = $data.postcode
          City = $data.city
          State = $data.state
          Country = $data.country
        }

      }
    Catch
    {
        Write-Host $_.Exception | format-list -force
    }
} | Export-Csv -NoTypeInformation -Append $csv_location

[1] 如果您将 数组 值发送到 Out-File,每个值都会成为其 自己的行 在输出文件中。虽然您可以使用 $userline -join ',' 来解决这个问题,但这样的 plain-text 处理很脆弱,因为带有 embedded , 字符的值。不会被正确处理。