导出CSV覆盖

时间:2018-08-03 21:01:08

标签: powershell csv export-to-csv

Part2List.csv:

Name,Date,Location
ADMRYANTEST1, 08/03/2018, 1
ADMRYANTEST2, 09/03/2018, 1

PowerShell命令:

Import-Csv -Path "C:\Part2List.csv" | Where-Object {$_.Date -gt (Get-Date)} | Export-Csv -Path "C:\Part2List.csv" -NoTypeInformation

(获取日期)今天是:2018年8月3日。该命令应仅擦除ADMRYANTEST1

为什么要删除我的整个文件?

3 个答案:

答案 0 :(得分:2)

  

为什么我的整个文件都被删除?

因为您无法在同一管道中读取和写入同一文件 ,除非您确保将输入文件全部读入内存, 之前的行通过管道发送。

为此,将用于读取输入文件的命令括在括号((...)中,以确保其运行完毕,并将所有输出收集在内存中,并将输入文件再次关闭,之前管道处理开始:

(Import-Csv -Path "C:\Part2List.csv") | # !! Note the (...)
  ... | 
    Export-Csv -Path "C:\Part2List.csv" -NoTypeInformation

请注意,如果在将所有数据写回到输入文件完成之前管道已中断,则此方法具有轻微的数据丢失风险

一种更强大的方法是先写入临时文件,然后在成功完成(仅)后替换原始文件。

无论采用哪种方法,如果原始文件都具有特殊权限,备用数据流……,您可能也想重新创建它们。


Theo's answer中指出,您还有一个其他问题 CSV列值始终作为字符串 > ,因此您必须根据需要执行显式转换

由于要进行日期比较,因此必须将$_.Date转换为[datetime]实例;因为您输入的格式为MM/dd/yyyy,这是不变区域性的 [1]  短日期模式,您可以广播[datetime]

(Import-Csv -Path "C:\Part2List.csv") | 
  Where-Object { [datetime] $_.Date -gt (Get-Date) } | 
    Export-Csv -Path "C:\Part2List.csv" -NoTypeInformation

[1]在大多数情况下,PowerShell使用不变文化[cultureinfo]::InvariantCulture)而非当前文化进行往返字符串转换上下文。有关更多信息,请参见this answer

答案 1 :(得分:1)

导入CSV后,$ _。Date保存一个字符串,而不是DateTime对象。稍后,您尝试将此字符串与当前日期(=对象)进行比较。 因为您说的格式是'MM / dd / yyyy',所以您应该执行类似的操作以使Powershell能够将其与DateTime对象进行比较。 这就是DateTime]::ParseExact()函数出现的地方:

Import-Csv -Path "C:\Part2List.csv" | Where-Object {([DateTime]::ParseExact($_.Date, "MM/dd/yyyy", [System.Globalization.CultureInfo]::InvariantCulture)) -gt (Get-Date)} | Export-Csv -Path "C:\Part2List_Output.csv" -NoTypeInformation -Force

此外,如果在CSV中找不到比今天还大的日期,则输出将为空。(csv中是否可能有将来的日期?)

请注意,我更改了输出的名称,因此您不会覆盖原始的csv文件

答案 2 :(得分:0)

不能在1行中使用该命令,因为按https://stackoverflow.com/a/48326987/6402199打开文件时文件被锁定。

此问题已解决!

wow