2014-10-20 132 views
0

我已经从网站上抓取了两个文件,以便列出我所在城市的公司。 第名单:姓名,城市,电话号码,电子邮件 第二名单:姓名,城市,电话号码Powershell:合并两个CSV文件与部分重复的行

我会有重复的行,如果我将它们合并,作为一个例子,我将有以下几种:

> "Firm1";"Los Angeles";"000000";"[email protected]" 
> "Firm1";"Los Angeles";"000000";"" 
> "Firm2";"Los Angeles";"111111";"" 
> "Firm3";"Los Angeles";"000000";"[email protected]" 
> "Firm3";"Los Angeles";"000000";"" 
> ... 

有没有办法合并两个文件,并保持这样的最大信息:

> "Firm1";"Los Angeles";"000000";"[email protected]" 
> "Firm2";"Los Angeles";"111111";"" 
> "Firm3";"Los Angeles";"000000";"[email protected]" 
> ... 

回答

0

根据实际情况你有这样的所谓“firm.csv”

文件0
"Firm1";"Los Angeles";"000000";"[email protected]" 
"Firm1";"Los Angeles";"000000";"" 
"Firm2";"Los Angeles";"111111";"" 
"Firm3";"Los Angeles";"000000";"[email protected]" 
"Firm3";"Los Angeles";"000000";"" 

可以使用加载:

$firms = import-csv C:\temp\firm.csv -Header 'Firm','Town','Tel','Mail' -Delimiter ';' 

然后

$firms | Sort-Object -Unique -Property 'Firm' 

据乔伊的评论我提高了解决方案:

$firms | Group-Object -Property 'firm' | % {$_.group | Sort-Object -Property mail -Descending | Select-Object -first 1} 
+0

请注意'Sort-Object'不能保证稳定的排序,所以你无法控制在这种情况下保留哪些行。很可能是那些没有电子邮件地址的人。 – Joey 2014-10-20 08:02:04

+0

我在很多制作脚本中使用它,你有一些'不稳定排序'的真实样本吗? – JPBlanc 2014-10-20 08:08:45

+0

这只是文档没有明确保证稳定性,这让我担心它会始终保持稳定。这可能现在甚至无限期地工作,但过去我一直被这样的事情咬过(不是在PowerShell中)。 – Joey 2014-10-20 08:14:29

0

必须有更好的方法,但这是做这件事的一个昂贵的方法。

$firms = import-csv C:\firm.csv -Header 'Firm','Town','Tel','Mail' -Delimiter ';' 

$Result = @() 
ForEach($i in $firms){ 

    $found = 0; 

    ForEach($m in $Result){ 

    if($m.Firm -eq $i.Firm){ 

     $found = 1 

     if($i.Mail.length -ne 0) 
     { 
      $m.Mail = $i.Mail 
     } 
     break; 
     } 
    } 

    if($found -eq 0){ 
     $Result += [pscustomobject] @{Firm=$i.Firm; Town=$i.Town; Tel=$i.Tel; Mail=$i.Mail} 
    } 
} 

$Result | export-csv C:\out.csv 
+0

你可能不应该在那里使用'-match',因为它会匹配子字符串(和'.'和其他正则表达式元字符可能有问题)。 '-eq'应该在那里做得很好。 – Joey 2014-10-20 08:55:53

+0

谢谢!你是对的。我将它改为-eq。 – 2014-10-20 09:11:30

0

编辑:刚才意识到两个文件不包含相同的标题。这是一个更新。

$main = Import-Csv firm1.csv -Header 'Firm','Town','Tel','Mail' -Delimiter ";" 
$alt = Import-Csv firm2.csv -Header 'Firm','Town','Tel' -Delimiter ";" 

foreach ($f in $alt) 
{ 
    $found = $false 
    foreach($g in $main) 
    { 
     if ($g.Firm -eq $f.Firm -and $g.city -eq $f.city) 
     { 
      $found = $true 

      if ($g.Tel -eq "") 
      { 
       $g.Tel = $f.Tel 
      } 
     } 
    } 
    if ($found -eq $false) 
    { 
     $main += $f 
    } 
} 


# Everything is merged into the $main array 
$main