首页 > 解决方案 > 使用 powershell 删除 .csv 文件中的最后一行

问题描述

我目前需要我们的一个自动化脚本的解决方案。作为该过程的一部分,它从源中获取文件,并且必须删除 .csv 中的最后一行并将其再次保存为 csv 文件(不确定为什么必须这样做,因为文件已经以 .csv 的形式出现,但没有它 - 它出错了)。问题是我似乎无法弄清楚如何删除最后一行。我想出了几个解决方案,但大多数只适用于 .txt 文件或对象。我现在拥有的是这样的:

Import-Csv $file | where {$_.'Search Status' -ne "Blank line"} | Export-Csv "\file.csv" -notypeinfo

它确实删除了写有“空白行”的最后一行,但它似乎只是删除了文本,当我的其他脚本解析文件时,它无法正确执行。综上所述 - 我需要一个脚本来获取这个文件,完全删除最后一行并将其再次保存为 .csv,因为“export-csv”似乎无法完成这项工作。

标签: powershellcsvscripting

解决方案


PSv5+中,您可以使用Select-Object's-SkipLast参数:

Get-Content $file | Select-Object -SkipLast 1 | Set-Content out.csv -Encoding UTF8

请注意,我只是使用Get-Content而不是Import-Csv,因为没有充分的理由产生Import-Csv(为每个输入行构造自定义对象)和后续Export-Csv(将每个自定义对象序列化为逗号分隔的值列表)的开销string) 如果唯一需要的任务是将一行作为一个整体删除。

另请注意,我已经包含一个-Encoding参数来说明您可能希望显式控制输出编码的观点,因为输入编码永远不会保留在 PowerShell 中。
Set-Content在 Windows PowerShell 上将默认为“ANSI”编码,在 PowerShell Core 上将默认为无 BOM 的 UTF-8。


PSv4-中,您可以使用以下技术进行模拟-SkipLast 1;它也允许您一次完成相同的操作,而无需将整个输入文件加载到内存中:

Get-Content $file | ForEach-Object { $prev = $null } {      
  if ($null -ne $prev) { $prev }
  $prev = $_
} | Set-Content out.csv -Encoding UTF8

以上只是将管道输入对象的输出延迟了一次迭代,这实际上省略了最后一个输入对象。


推荐阅读