使用powershell删除.csv文件中的最后一行

0tdrvxhp  于 2023-09-28  发布在  Shell
关注(0)|答案(6)|浏览(170)

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

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

它确实删除了最后一行写有“空行”的内容,但它似乎只是删除了文本,当我的其他脚本解析文件时,它无法正确执行。因此,总结-我需要一个脚本,将此文件,完全删除最后一行,并再次保存为.csv作为“导出-csv”似乎没有做这项工作。

wz1wpwve

wz1wpwve1#

在**PSv 5 +**中可以使用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的UTF-8编码。
在**PSv 4-**中,您可以使用以下技术模拟-SkipLast 1:它也允许你在一次传递中做同样的事情,而不需要将整个输入文件加载到内存中:

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

上面简单地将流水线输入对象的输出延迟一次迭代,这有效地省略了 last 输入对象。

gkl3eglg

gkl3eglg2#

  • 导入csv
  • 获取项目计数
  • 选择第一个(count - 1)行
  • 出口
$FileIn = '.\file.csv'
$FileOut= '.\file2.csv'
$csv = Import-Csv $FileIn
$csv | Select-Object -First ($csv.count -1) |
    Export-Csv $FileOut  -NoTypeInformation
laawzig2

laawzig23#

还是

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

以保存执行[array]::Reverse()两次

1tuwyuhd

1tuwyuhd4#

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

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

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

v6ylcynt

v6ylcynt5#

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

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

hmae6n7t6#

我们有一些额外的要求,例如能够检查文件夹中的多个文件,并确保第一行中的列数与最后一行中的列数相匹配。有时文件在传输过程中会中断,并在文件中留下最后一个不完整的行。在这里发布我们的解决方案,以防它可能会帮助其他人:

$path = "."
$enc = "utf8" # file encoding
$delim = '\t' # column separator, tab in this example
$terminator = "`n" # LF (unix style row terminators)
$pattern = "^.*Example\.txt$"
# ----===================================================================================----
$files = @(Get-ChildItem FileSystem::"$path" | Where-Object {$_.Name -match $pattern})
ForEach ($file in $files) {
    $filename = $file.FullName
    # count number of columns in the first row and then compare with last row
    $head_count = ((Get-Content $filename -Head 1) -split $delim).Count
    $tail_count = ((Get-Content $filename -Tail 1) -split $delim).Count
    If($head_count -ne $tail_count) {
        Write-Output "MODIFYING: $filename ($head_count head and $tail_count tail columns)"
        Copy-Item $filename -Destination "$filename.original"
        (Get-Content "$filename.original" | Select -SkipLast 1) -join $terminator | Out-File -NoNewline -Encoding $enc $filename
    }
    Else {
        Write-Output "NO ACTION: $filename ($head_count head and $tail_count tail columns)"
    }
}

相关问题