使用上面单元格中的数据填充csv文件中的单元格

时间:2015-07-28 14:06:56

标签: csv powershell

我有一个CSV文件,其中包含以下订单信息:

OrderNo     SKU     PaidDate     BuyerName         Buyer Address     Buyer Phone No.
NG0001      ABC1    20150727     MR A. SMITH       1 HIGH STREET     01234 567890
NG0001      DEF2              
NG0001      XYZ3      
NG0002      ABC1    20150728     MRS B. JONES      100 LONDON ROAD   07766 554433
NG0002      DEF2    

我需要使用上面列中的数据填充空列(基于订单号),因此它变为:

OrderNo     SKU     PaidDate     BuyerName         Buyer Address     Buyer Phone No.
NG0001      ABC1    20150727     MR A. SMITH       1 HIGH STREET     01234 567890
NG0001      DEF2    20150727     MR A. SMITH       1 HIGH STREET     01234 567890
NG0001      XYZ3    20150727     MR A. SMITH       1 HIGH STREET     01234 567890
NG0002      ABC1    20150728     MRS B. JONES      100 LONDON ROAD   07766 554433
NG0002      DEF2    20150728     MRS B. JONES      100 LONDON ROAD   07766 554433

我可以在Excel公式中通过比较行之间的顺序号并引用上面的单元格来实现这一点(如果它们相同),但是无法解决如何在Powershell中执行相同的操作 - 有没有办法做类似于这样:

ForEach-Object {if ($_.OrderNo=$_.OrderNo in row above) $_.PaidDate=$_.PaidDate in row above;}

或者我是否完全以错误的方式解决这个问题,并且需要以更少的Excel,更多的Powershell-y方式重新思考?

3 个答案:

答案 0 :(得分:0)

这应该适合你:

$Data = Import-Csv "C:\temp\Testing.csv"

$i = 0
foreach ($Entry in $Data) {
    if ($Entry.PaidDate -eq "" -and $i -ne 0 -and $Data[$i].OrderNo -eq $Data[$i - 1].OrderNo) {
        $Data[$i].PaidDate = $Data[$i - 1].PaidDate
        $Data[$i].BuyerName = $Data[$i - 1].BuyerName
        $Data[$i].'Buyer Address' = $Data[$i - 1].'Buyer Address'
        $Data[$i].Buyer = $Data[$i - 1].Buyer
        $Data[$i].'Phone No.' = $Data[$i - 1].'Phone No.'
    }

    $i++
}

$Data

它的作用是测试一个空的PaidDate,如果是这样的话(以及它是不是第一行,同样如果它是第一行)与前一个条目相同OrderNo)然后它将属性设置为等于它上面的属性。

运行后,$Data包含已填充的数据,您可以从那里处理(即将其输出回CSV文件等)。

答案 1 :(得分:0)

我对此的解释是,基本上SKU是唯一正在发生变化的事情。将文件作为CSV读入PowerShell,然后计算我们将用作模板的主行。当我们查看每一行时,将其内容单独匹配到其关联的主行。

# All of the data of the CSV file
$allData = Import-Csv "c:\temp\test.csv"

# Rows with complete data to be used as templates.
$masterRows = $allData | Where-Object{$_."PaidDate" -and $_.BuyerName -and $_."Buyer Address" -and $_."Buyer Phone No."}

$allData | ForEach-Object{
    $singleRow = $_
    $newRow = $masterRows | Where-Object{$singleRow.OrderNo -eq $_.OrderNo} 
    $newRow.SKU = $singleRow.SKU
    $newRow
} | Export-CSV -NoTypeInformation "C:\temp\output.csv"

在我们浏览每一行时,我们只是将orderno行与$masterRows中的匹配等效词匹配。然后获取$masterRow的副本并更新其SKU,然后再将其发送到管道。

答案 2 :(得分:0)

首先,我设置一个包含csv数据的字符串,然后将其导出到文件中。

$csv1 = @"
OrderNo,SKU,PaidDate,BuyerName,Buyer Address,Buyer Phone No.
NG0001,ABC1,20150727,MR A. SMITH,1 HIGH STREET,01234 567890
NG0001,DEF2
NG0001,XYZ3
NG0002,ABC1,20150728,MRS B. JONES,100 LONDON ROAD,07766 554433
NG0002,DEF2
"@

$csv1 | Set-Content csvfile1.csv

然后再次导入文件

$actual = Import-Csv csvfile1.csv

使用powershell Group-Object CmdLet按OrderNo分组

$grouper = $actual | Group-Object -Property OrderNo

foreach ($group in $grouper)
{
    # Save properties from first item in group
    $paiddate = $group.Group[0].PaidDate
    $buyername = $group.Group[0].BuyerName
    $buyerAddress = $group.Group[0].'Buyer Address'
    $buyerPhoneNo = $group.Group[0].'Buyer Phone No.'
    # Copy properties if empty
    foreach ($item in $group.Group)
    {
        if ($item.PaidDate -eq $null){$item.PaidDate = $paiddate}
        if ($item.BuyerName -eq $null){$item.BuyerName = $buyername}
        if ($item."Buyer Address" -eq $null){$item."Buyer Address" = $buyerAddress}
        if ($item."Buyer Phone No." -eq $null){$item."Buyer Phone No." = $buyerPhoneNo}
    }
}

显示结果

$actual


OrderNo         : NG0001
SKU             : ABC1
PaidDate        : 20150727
BuyerName       : MR A. SMITH
Buyer Address   : 1 HIGH STREET
Buyer Phone No. : 01234 567890

OrderNo         : NG0001
SKU             : DEF2
PaidDate        : 20150727
BuyerName       : MR A. SMITH
Buyer Address   : 1 HIGH STREET
Buyer Phone No. : 01234 567890

OrderNo         : NG0001
SKU             : XYZ3
PaidDate        : 20150727
BuyerName       : MR A. SMITH
Buyer Address   : 1 HIGH STREET
Buyer Phone No. : 01234 567890

OrderNo         : NG0002
SKU             : ABC1
PaidDate        : 20150728
BuyerName       : MRS B. JONES
Buyer Address   : 100 LONDON ROAD
Buyer Phone No. : 07766 554433

OrderNo         : NG0002
SKU             : DEF2
PaidDate        : 20150728
BuyerName       : MRS B. JONES
Buyer Address   : 100 LONDON ROAD
Buyer Phone No. : 07766 554433

希望它能为你效劳。