我有一个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方式重新思考?
答案 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
希望它能为你效劳。