【问题标题】:Consolidate data with import CSV使用导入 CSV 合并数据
【发布时间】:2018-01-29 13:08:51
【问题描述】:

我正在尝试找到一种在导出之前收集数据的方法,以便从文件中获取更多数据并合并然后导出。

我的代码是这样的:从多个来源查找用户和计算机并合并数据 → 创建 2 列(名称、计算机)的数组 → 将该数据导出到 output.log

因为我要查找的数据会不时动态变化,所以我希望每天多次运行脚本,所以 下次运行从 output.log 中获取数据到数组中 → 继续收集新数据并将它们添加到现有的 output.log 中。

目前我被困在每次运行代码时都会覆盖 output.log 的位置。

我的代码是这样的:

Set-Variable -Name Computer -Value @("pc1","pc2")
Set-Variable -Name LogNames -Value @("something")

$el_c = @()
foreach ($comp in $Computer) {
  foreach ($log in $LogNames) {
    $el = ...    # get data I need from $comp
    $el_c += $el  #consolidating
  }
}

$el_c | %{
  $_ | select @{n='Name';e={$_.Properties[0].value}}, @{n='Computer';e={$_.Properties[1].value}}
} | Export-Csv "C:\test\OutputRaw.log"
$input = 'C:\test\OutputRaw.log'  #TO FILTER OUT DUPLICATION
$inputCsv = Import-Csv $input | Sort-Object * -Unique 
$inputCsv | Export-Csv "C:\test\OutputFinal.log" -NoTypeInformation

输出是:

“名称”、“计算机” "丹","PC1" "汤姆","PC2"

如何在提取到文件之前实现它,还从“output.log”获取数据并合并/添加/合并到新收集的数据中?

【问题讨论】:

  • 您想如何“整合”数据?您只想继续附加到output.log 吗?或者如果新数据匹配(不匹配?)一些现有数据,是否应该省略?
  • 输出的结构应该是一样的,一列name,另一列Computer。因为导入的数据与几小时前导出的数据相同,所以我只想将新数据添加到文件中。
  • 这不能回答我的问题。您要添加所有新数据还是仅添加一些新数据?
  • 正如您在代码中看到的那样,当它查询数据时,它是名称和计算机的“选择对象”,然后导出到文件中,下次它只添加新收集的数据(选择名称+计算机)数据到现有文件中(如 -append),但以某种方式避免重复

标签: powershell csv export-to-csv import-csv


【解决方案1】:

使用Export-CSV-Append参数:

Export-Csv "C:\test\Output.log" -Append

【讨论】:

  • 差不多好了,问题是它会将新数据添加到文件底部,我仍然卡在潜在的重复中
【解决方案2】:

假设已经创建了一个日志(我称之为Log.csv)($Computer | Export-CSV .\Log.csv):

Import-CSV .\Log.csv | LeftJoin $Computer Name -Merge {$Right.$_} | Export-CSV .\Log.csv

LeftJoinJoin-Object)的详细信息,请参阅:https://*.com/a/45483110/1701026

【讨论】:

    【解决方案3】:

    感谢 Paul 的帮助,我使用了 -Append,然后在最后添加了另一个过滤器重复项。

    $el_c | %{
      $_ | select @{n='Name';e={$_.Properties[0].value}}, @{n='Computer';e={$_.Properties[1].value}}
    } | Export-Csv "C:\test\OutputRaw.log"
    $input = 'C:\test\OutputRaw.log'
    $inputCsv = Import-Csv $input | Sort-Object * -Unique
    $inputCsv | Export-Csv "C:\test\OutputFinal.log" -Append -NoTypeInformation
    $input = 'C:\test\OutputFinal.log'
    $inputCsv = Import-Csv $input | Sort-Object * -Unique
    $inputCsv | Export-Csv "C:\test\OutputFinal.log"  -NoTypeInformation
    

    【讨论】:

      【解决方案4】:

      使用管道和Compare-Object。将select 语句移动到内部foreach 循环中。

      $Computer = 'pc1', 'pc2'
      $LogNames = 'something'
      
      $csv = 'C:\test\OutputFinal.log'
      $ref = Import-Csv $csv
      
      $Computer | ForEach-Object {
        $comp = $_
        foreach ($log in $LogNames) {
          ... |      # get data from $comp
            select @{n='Name';e={$_.Properties[0].value}},
                   @{n='Computer';e={$_.Properties[1].value}}
        }
      } | Where-Object {
        Compare-Object $_ $ref -Property 'Name','Computer' -IncludeEqual -ExcludeDifferent
      } | Export-Csv $csv -Append -NoType
      

      【讨论】: