我有一个包含许多列的CSV,第一列中的数据是日期,但格式错误。我只能选择第一列并重新格式化日期,但我无法弄清楚如何将新数据保存到现有CSV而不会覆盖所有其他数据。
$File = "File.csv"
$Content = Get-Content $File
$timestamp = @()
$timestamp += '"' + "timestamp" + '"'
$timestamp += $Content | Foreach { $_.Split(",") | select -first 1 } | select -skip 1 -last 10000 | where {$_ -notmatch "timestamp"} | foreach {($_).Substring(1,$_.Length-2)} | foreach {get-date ($_).ToString() -Format s} | foreach {'"' + $_ + '"'}
在:
"timestamp"
"17-Dec-2014 07:00:00 AM"
"17-Dec-2014 07:15:00 AM"
"17-Dec-2014 07:30:00 AM"
"17-Dec-2014 07:45:00 AM"
"17-Dec-2014 08:00:00 AM"
后:
"timestamp"
"2014-12-17T07:00:00"
"2014-12-17T07:15:00"
"2014-12-17T07:30:00"
"2014-12-17T07:45:00"
"2014-12-17T08:00:00"
答案 0 :(得分:2)
在文件c:\temp\test.csv
old_timestamp timestamp
12/17/2014 7:00 12/17/2014 7:00
12/17/2014 7:15 12/17/2014 7:15
12/17/2014 7:30 12/17/2014 7:30
12/17/2014 7:45 12/17/2014 7:45
12/17/2014 8:00 12/17/2014 8:00
我会做这样的事情。操作old_timestamp“列”并将更改输出回管道。
Import-CSV C:\temp\test.csv | ForEach-Object{
$_.old_timestamp = get-date $_.old_timestamp -Format s
$_
}
示例输出:
old_timestamp timestamp
------------- ---------
2014-12-17T07:00:00 12/17/2014 7:00
2014-12-17T07:15:00 12/17/2014 7:15
2014-12-17T07:30:00 12/17/2014 7:30
2014-12-17T07:45:00 12/17/2014 7:45
2014-12-17T08:00:00 12/17/2014 8:00
现在你可以随心所欲地做它,就像输出回文件一样!
Import-CSV C:\temp\test.csv | ForEach-Object{
$_.old_timestamp = get-date $_.old_timestamp -Format s
$_
} | Export-Csv C:\temp\updated_test.csv -NoTypeInformation
Simlar方法
您可以使用可以执行相同操作的Select-Object
语句
Import-CSV C:\temp\test.csv |
Select-Object @{Name="New_TimeStamp";Expression = {get-date $_.old_timestamp -Format s}},* -ExcludeProperty old_timestamp
这仅在列名不同时才有效。它将通过指定New_TimeStamp
将格式化的列输出为*
以及其余数据。从我所看到的你的其他问题来看,这可能不会与他们融洽,但这是一个解决方案。
答案 1 :(得分:2)
使用System.DateTime
类的ParseExact()
方法将字符串输入解析为日期,并通过ToString()
方法将日期转换回格式化字符串。
$csv = 'C:\path\to\your.csv'
$culture = [Globalization.CultureInfo]::InvariantCulture
$srcfmt = 'dd-MMM-yyyy hh:mm:ss tt'
$dstfmt = 'yyyy-MM-ddTHH:mm:ss'
(Import-Csv $csv) | % {
$date = [DateTime]::ParseExact($_.timestamp, $srcfmt, $culture)
$_.timestamp = $date.ToString($dstfmt)
$_ # required to inject the current object back into the pipeline
} | Export-Csv $csv -NoType
您可以将其替换为calculated property,而不是使用循环来更新timestamp
属性:
$csv = 'C:\path\to\your.csv'
$culture = [Globalization.CultureInfo]::InvariantCulture
$srcfmt = 'dd-MMM-yyyy hh:mm:ss tt'
$dstfmt = 'yyyy-MM-ddTHH:mm:ss'
(Import-Csv $csv) |
select @{n='timestamp';e={
[DateTime]::ParseExact($_.timestamp, $srcfmt, $culture).ToString($dstfmt)
}}, other, properties, here, ... |
Export-Csv $csv -NoType
请注意,必须在子表达式中运行Import-Csv
(或首先在变量中捕获其输出),否则文件仍会在{{1开始写它。