【问题标题】:Use powershell to remove last row in .csv file使用 powershell 删除 .csv 文件中的最后一行
【发布时间】:2018-12-29 04:07:40
【问题描述】:

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

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

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

【问题讨论】:

    标签: powershell csv scripting


    【解决方案1】:

    PSv5+中你可以使用Select-Object-SkipLast参数:

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

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

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


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

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

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

    【讨论】:

    • 嗯。 -SkipLast 没有文档(即使参数名称很明显)。
    • @TheIncorrigible1:好点:它没有描述,但它被列出(作为 v6 文档中语法图的一部分;在 v5.1 和 v5.0 文档中,它在正文中也有一个 parameter-details 段落,但仍然缺少描述);见github.com/PowerShell/PowerShell-Docs/issues/2716
    • @TheIncorrigible1,我为此做了 PR,现在 -SkipLast 描述已上线(仍需合并为 v5)。仅供参考
    【解决方案2】:
    • 导入 csv
    • 获取商品数量
    • 选择第一个(计数 - 1)行
    • 导出

    $FileIn = '.\file.csv'
    $FileOut= '.\file2.csv'
    $csv = Import-Csv $FileIn
    $csv | Select-Object -First ($csv.count -1) |
        Export-Csv $FileOut  -NoTypeInformation
    

    【讨论】:

      【解决方案3】:

      或者做

      $x = @(Get-Content -Path $file)
      ($x[0..($x.Length - 2)]) | Out-File -FilePath $file
      

      避免重复两次[array]::Reverse()

      【讨论】:

        【解决方案4】:

        您可以将文件加载到对象中,删除最后一行,然后重新编写:

        $f = @(Get-Content -Path $file)
        [array]::Reverse($f)
        $f = $f | Select-Object -Skip 1
        [array]::Reverse($f)
        $f | Out-File -FilePath $file
        

        注意:这对我来说非常懒惰(并且表现不佳),因为我没有花更多时间考虑它,但它完成了工作。

        【讨论】:

          【解决方案5】:

          根据您的 powershell 版本,您可以使用 Select-Object 的 skiplast 参数

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

          【讨论】:

            猜你喜欢
            • 2012-07-23
            • 1970-01-01
            • 2023-03-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多