我仍然在研究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
这是我第一次尝试自定义对象,所以任何帮助都会受到赞赏。
答案 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