Powershell:将多行合并为一行

时间:2015-02-06 14:08:22

标签: powershell csv

我有一个 .csv 文件,如下所示:

employeenumber;phone;mobile;fax;userid;Email
99999991;+1324569991;+234569991;+5234569991;user01;user1@domain.com
99999992;+1234569992;+234569992;;user02;user2@domain.com
99999993;+1234569993;+234569993;;user03;user3@domain.com
99999993;+12345699933;;;user03;user3@domain.com
99999993;;;+5234569993;user03;user3@domain.com
99999994;+1234569994;;;user04;user4@domain.com

正如您所看到的,有不同的 employeenumbers 和一些具有相同 employeenumber 的行。

有没有办法在powershell中使用相同的 employeenumber 合并这些行?

类似输出:

employeenumber;phone;mobile;fax;userid;Email
99999991;+1324569991;+234569991;+5234569991;user01;user1@domain.com
99999992;+1234569992;+234569992;;user2;user2@domain.com
99999993;+1234569993 / +12345699933;+234569993;+5234569993;user03;user3@domain.com
99999994;+1234569994;;;user04;user4@domain.com

谢谢

2 个答案:

答案 0 :(得分:1)

我会试一试:

(@'
employeenumber;phone;mobile;fax;userid;Email
99999991;+1324569991;+234569991;+5234569991;user01;user1@domain.com
99999992;+1234569992;+234569992;;user02;user2@domain.com
99999993;+1234569993;+234569993;;user03;user3@domain.com
99999993;+12345699933;;;user03;user3@domain.com
99999993;;;+5234569993;user03;user3@domain.com
99999994;+1234569994;;;user04;user4@domain.com
'@).split("`n") |
foreach {$_.trim()} | sc test.csv

$ht = @{}
$props = (Get-Content test.csv -TotalCount 1).split(';')

import-csv test.csv -Delimiter ';' |
foreach {
 if ( $ht.ContainsKey($_.employeenumber) )
  {
    foreach ($prop in  $props )
     { 
       if ($_.$prop )
        {$ht[$_.employeenumber].$prop = $_.$prop }
     }
  }

  else { $ht[$_.employeenumber] = $_ }
 }

 $ht.values | sort employeenumber



employeenumber : 99999991
phone          : +1324569991
mobile         : +234569991
fax            : +5234569991
userid         : user01
Email          : user1@domain.com

employeenumber : 99999992
phone          : +1234569992
mobile         : +234569992
fax            : 
userid         : user02
Email          : user2@domain.com

employeenumber : 99999993
phone          : +12345699933
mobile         : +234569993
fax            : +5234569993
userid         : user03
Email          : user3@domain.com

employeenumber : 99999994
phone          : +1234569994
mobile         : 
fax            : 
userid         : user04
Email          : user4@domain.com

答案 1 :(得分:1)

我已经开枪了。我相信我的回答比Mjolinor更容易阅读。

我根据使用Group-Object命令将CSV中的条目分组为$ singletons或$ duplicates。然后,我通过$ duplicates管道并合并在电话,移动或传真字段中找到的记录,使用您指示的'/'字符。

#$csv = get-content .\CSVNeedstoMerge.csv
$csvValues = $csv | ConvertFrom-Csv -Delimiter ';'
$duplicates = $csvValues | group-object EmployeeNumber | ? Count -gt 1
$objs = New-Object System.Collections.ArrayList

$singletons = $csvValues | group-object EmployeeNumber | ? Count -eq 1  | %     {$objs.Add($_.Group)}

ForEach ($duplicate in $duplicates){
$objs.Add([pscustomobject]@{employeenumber=($duplicate.Group.employeenumber  | select -Unique) -as [int];
    phone=($duplicate.Group.phone | ? Length -gt 0) -join '/';
    mobile=($duplicate.Group.mobile| ? Length -gt 0) -join '/';
    fax=($duplicate.Group.fax | ? Length -gt 0) -join '/';
    userid = $duplicate.Group.userid | select -Unique
    email= $duplicate.Group.email  | select -Unique })
}

$objs | Sort EmployeeNumber