从特定CSV列计算并输出到新文件

时间:2014-10-16 07:52:46

标签: powershell csv

我正在尝试从一个CSV文件导入数据,使用导入的数据进行一些计算,然后将其保存到新的CSV文件中,并且我在过去一天都没有运气。

摘要:

我有一个管道分隔的CSV,其中包含数据列:

colA,colB,colC,colD,colE

colA是字符串格式的日期时间“20/01/2011 14:20:00”(dd / MM / yyyy HHmmss)

colC是一个数字

我需要读取初始CSV,然后从colA中的值中进行两次计算: 1 - 2000年1月1日以来的天数 2 - 从午夜开始的分钟数。

data.csv中的示例数据:

01/01/2011 14:20:00|10|6|10|192.168.11.7|
01/01/2011 14:25:00|2|0|10|192.168.11.7|
01/01/2011 14:30:00|4|8|10|192.168.11.7|
01/01/2011 14:35:00|6|9|10|192.168.11.7|

然后我需要将计算出的数据输出到新的CSV文件中,该文件还添加了一些硬编码值/列(原始dta,无标题):

(自2000年1月1日起的天数),(从午夜起的分钟数),5,(colC值),1,文字,A,0

**括号中的值是从原始CSV计算/或传递的。所有其他值都硬编码到每个CSV ROW中。

因此,对于上面的示例数据,新输出将是(为了格式化目的,我再次添加额外的换行符):

4018,860,5,6,1,Text,A,0
4018,865,5,0,1,Text,A,0
4018,870,5,8,1,Text,A,0
4018,875,5,9,1,Text,A,0

我可以将字段解析为这样的数组:

$data = Import-Csv c:\data.csv -Header colA, colB, colC, colD, colE -Delimiter '|' | Select-Object colA, colC
$newdata += $data
$newdata | convertto-csv -NoTypeInformation -Delimiter ',' | foreach-object {$_} | Out-File c:\newfile.csv

这会给我我追求的两个字段,但我无法执行计算并添加新CSV中所需的额外硬编码字段。

在过去的一天里,我一直在谷歌搜索并尝试了许多不同的方式,但我仍然无处可去。

有人可以提供一些帮助吗?谢谢。

1 个答案:

答案 0 :(得分:2)

这样的事情应该让你开始

$path = "E:\temp\sample.csv"
$y2k = Get-Date -Date 1/1/2000
Import-Csv $path -Header colA, colB, colC, colD, colE -Delimiter '|' | ForEach-Object{
    $colADate = [datetime]::ParseExact($_.ColA,"dd/MM/yyyy HH:mm:ss",[System.Globalization.CultureInfo]::InvariantCulture)
    $minutesFromMidnight = $colADate.TimeOfDay.TotalMinutes
    $daysSincey2k = New-TimeSpan -Start $y2k -End $colADate | Select-Object -ExpandProperty Days
    [PSCustomObject][ordered]@{
        DaysSince = $daysSincey2k
        MinutesSince = $minutesFromMidnight
        ColA = $_.Cola
        ColB = $_.Colb
        ColC = $_.Colc
        ColD = $_.Cold
        ColE = $_.Cole
    }
}

您可以使用Select-Object表达式将其设为单行,但这应该更容易阅读。你应该至少需要PowerShell 3.0来实现这个目的。如果你没有它,这只需要微小的调整。这是您的数据的输出

DaysSince MinutesSince ColA                ColB ColC ColD ColE        
--------- ------------ ----                ---- ---- ---- ----        
     4018          860 01/01/2011 14:20:00 10   6    10   192.168.11.7
     4018          865 01/01/2011 14:25:00 2    0    10   192.168.11.7
     4018          870 01/01/2011 14:30:00 4    8    10   192.168.11.7
     4018          875 01/01/2011 14:35:00 6    9    10   192.168.11.7

如果您使用方法ParseExact的时间格式相同,则会将其转换为DateTime对象。这允许我们使用New-TimeSpan确定时间差异。使用计算字段创建自定义对象并添加计算数据。

从评论更新

对于您要查找的静态输出,我将更改[pscustomobject],如下所示以及添加export-csv调用

    [PSCustomObject][ordered]@{
        DaysSince = $daysSincey2k
        MinutesSince = $minutesFromMidnight
        Five = 5
        ColC = $_.Colc
        One = 1
        Text = "Text"
        Bee = "B"
        Zero = 0
    }
} | Export-Csv -Path c:\newfile.csv -NoTypeInformation

对于2.0,这应该有效

    $props = @{
        DaysSince = $daysSincey2k
        MinutesSince = $minutesFromMidnight
        Five = 5
        ColC = $_.Colc
        One = 1
        Text = "Text"
        Bee = "B"
        Zero = 0
    }

    New-Object PSObject -Property $props
} | Select-Object DaysSince,MinutesSince,Five,ColC,One,Text,Bee,Zero | Export-Csv -Path c:\temp\newfile.csv -NoTypeInformation