在自定义Powershell对象上组合成员

时间:2013-11-21 17:02:43

标签: powershell powershell-v2.0

我仍然在研究this question更好的方法,我决定尝试创建一个可以导出到csv的自定义对象。我有基本的工作,可以提取我需要的信息,但现在我想将具有重复键值的成员组合成一行。我在导出之前尝试对ID字段进行分组,并使用“if”语句查看ID号是否已经存在,如果是,则更新相应的字段,但我似乎无法使其工作。我还需要为每一行添加一笔金额。

$SourceFile = "C:\ACT20131107.TXT"
$objectCollection = ForEach($match in Select-String -path $SourceFile -pattern "242200", "242201") {      

# Convert the match OBJECT to a string for matching
$string = $match.Line

# Set variables
$Amt2 = "{0:n2}" -f 0
$Amt1 =  "{0:n2}" -f 0
$ID = $($string.substring(93,10)).replace("CAR","C")

if ($string -match "242200") {
    $Amt2 = $($string.substring(40,13)).Insert(11,'.')
}
else {
    $Amt1 = $($string.substring(40,13)).Insert(11,'.')
}

$properties = @{ID = $ID;Date = $string.substring(3,8);State = $string.substring(32,2);AmtF = $Amt1;AmtS = $Amt2} 
New-Object -TypeName PSObject -Property $properties                                       
} 

$objectCollection | export-csv "C:\test2.csv" -NoTypeInformation

当前输出:

ID       AmtF           AmtS           Date     State
--       ----           ----           ----     -----
C0044822 0.00           00000000227.82 20131107 MO   
C0010079 0.00           00000000405.41 20131107 NC   
C0027859 00000000848.31 0.00           20131107 FL   
C0010079 00000001291.00 0.00           20131107 MO   
C0044822 00000001351.35 0.00           20131107 NC   

期望的输出:

ID       AmtF           AmtS           Date     State
--       ----           ----           ----     -----  
C0027859 00000000848.31 00000000000.00 20131107 FL   
C0010079 00000001291.00 00000000405.41 20131107 MO   
C0044822 00000001351.35 00000000227.82 20131107 NC  
Totals   00000003490.66 00000000633.23

这是我第一次尝试自定义对象,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我认为你真的很亲密。我有一些我认为可行的方法,但由于我原始格式没有任何样本数据,我无法确定。

这不是最漂亮的解决方案,但我认为它会让你到达你想去的地方,而不用希望破坏你的原始代码。

$SourceFile = "C:\ACT20131107.TXT"
# This hashtable is to store all unique ids and keep a running tally of AmtS and AmtF while you loop through the lines of the original file.
$dataHash = @{}

$objectCollection = ForEach($match in Select-String -path $SourceFile -pattern "242200", "242201") {      

# Convert the match OBJECT to a string for matching
$string = $match.Line

# Set variables
$Amt2 = "{0:n2}" -f 0
$Amt1 =  "{0:n2}" -f 0
$ID = $($string.substring(93,10)).replace("CAR","C")

if ($string -match "242200") {
    $Amt2 = $($string.substring(40,13)).Insert(11,'.')
}
else {
    $Amt1 = $($string.substring(40,13)).Insert(11,'.')
}

# In Powershell, 
if(!$dataHash.ContainsKey($ID))
{
    # This prevents you from trying to reference into a null collection in the next few lines.
    $dataHash[$ID] = @{}
}
# In Powershell, you can reference into a hashtable with a non existant key, and it will be added, and null values are the equivalent of 0 values for basic math ops.
$dataHash[$ID]["State"] = $string.substring(32,2);
$dataHash[$ID]["Date"] = $string.substring(3,8)
$dataHash[$ID]["AmtF"] += $Amt1
$dataHash[$ID]["AmtS"] += $Amt2
}

# Select out custom objects to make summations and csv export easier.
$properties = @(
    @{Name="ID";Expression={$_}},
    @{Name="Date";Expression={$dataHash[$_][Date]}}
    @{Name="AmtF";Expression={$dataHash[$_]["AmtF"]}}
    @{Name="Amts";Expression={$dataHash[$_]["AmtS"]}}
    @{Name="State";Expression={$dataHash[$_]["State"]}}
)
$dataForCsv = $dataHash.Keys | Select $properties

#Time to sum up, then add a custom object to the output data for the totals.
$AmtFTotals = ($dataForCsv | Measure-Object -Properties AmtF -Sum).Sum
$AmtSTotals = ($dataForCsv | Measure-Object -Properties AmtS -Sum).Sum
$dataForCsv += New-Object PSCustomObject @{ID="Totals";AmtF=$AmtFTotals;AmtS=$AmtSTotals;Date=$null;State=$null}
$dataForCsv | export-csv "C:\test2.csv" -NoTypeInformation