【问题标题】:Delete first 15 lines from multiple CSV files in one folder using Powershell使用 Powershell 从一个文件夹中的多个 CSV 文件中删除前 15 行
【发布时间】:2019-01-31 23:16:59
【问题描述】:

我有一个 Powershell 脚本,可以从单个 CSV 文件中巧妙地删除前 15 行。

$import = get-content c:\temp\test.csv
$import | Select-Object -Skip 15 | Set-Content c:\temp\test2.csv

我想循环访问单个文件夹中的多个 CSV 文件。无法完全弄清楚如何做到这一点。

【问题讨论】:

  • 我不需要工具来测试,但从记忆中这应该可以工作:Import-Csv -Path C:\temp\text.csv | Select-Object -Skip 15 | Export-Csv -Path C:\temp\test2.csv -NoTypeInformation
  • 使用Get-ChildItem 获取文件列表,然后通过管道遍历该列表到ForEach-Object,将您的代码放入“F-O”循环中。这似乎可以涵盖您的任务。 [咧嘴]

标签: powershell csv


【解决方案1】:

这是一个单管道解决方案,它将文件作为文本文件处理并跳过前15个数据,即保留标题行(CSV 文件中的第一行,其中包含列名),并将每个*.csv 文件的结果保存到相应的*2.csv 文件中

Get-ChildItem c:\temp -Filter *.csv | ForEach-Object {
  Get-Content $_.FullName | 
    Where-Object { $_.ReadCount -eq 1 -or $_.ReadCount -ge 17 } |  
      Set-Content ($_.FullName -replace '\.csv$', '2$&')
}

注意:要无条件删除前 15 行,请将Where-Object 命令替换为:
Select-Object -Skip 15

注意.ReadCount 属性的使用,它包含输入的行号。 Get-Content 将此属性添加到它从输入文件中读取的每一行中。

将 CSV 文件处理为 文本 文件(使用 Get-Content / Set-Content 而不是 Import-Csv / Export-Csv)允许 更快的处理(并保留值周围是否存在双引号),但有一个警告,假设 文本行CSV 行相同:虽然 CSV 通常与文本文件 相同,但不是 em>必然 true:CSV 列值,如果 "..."-enclosed,可能跨越多行

另请注意,在 Windows PowerShell 中,Set-Content 默认会创建“ANSI”编码的输出文件,无论输入编码如何;在 PowerShell Core 中,您最终会得到无 BOM 的 UTF-8 编码文件。 使用-Encoding 控制输出编码。

【讨论】:

    【解决方案2】:

    可选-NumberOfLines参数,默认为15

    可选的-Verbose参数将输出修改后的文件。

    function Remove-CSVLines {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory)]
            [string]$FolderPath,
    
            [int]$NumberOfLines = 15
        )
        process{
            $fileList = (Get-ChildItem -Path $FolderPath -Filter '*.csv')
    
            foreach ($file in $fileList){
                $csvObject = Import-Csv -Path $file.PSPath
                $csvObject | Select-Object -Property * -Skip $NumberOfLines | Export-CSV -Path $file.PSPath -Force -NoTypeInformation
                Write-Verbose -Message "Removed $NumberOfLines lines from $file"
            }
        }
    }
    
    Remove-CSVLines -FolderPath .\myfolder
    

    【讨论】:

    • 您已经很好地打包了功能,但归根结底,我认为打包有点分散了解决方案的本质。事实证明(问题并不明显),OP 确实想从文件中删除前 15 行 lines,这些文件显然包含非 CSV 数据。您的解决方案适用于应删除前 15 个 数据行 的正确 CSV 文件,但请注意,通过 Import-CsvExport-Csv 进行的往返既昂贵又可能会改变文件(-Encoding 是你的朋友,后者)。
    • 请注意Select-Object -Property * 不必要地创建输入对象的副本;在这种情况下,并且出于(重新)导出到 CSV 的目的,这只是效率低下,但请注意,使用非自定义对象作为输入时,信息可能会丢失。简而言之:使用Select-Object -Property * -Skip $NumberOfLines 跳过$NumberOfLines 对象,并通过as-is 传递剩余的对象。
    • 感谢您的解释。您介意扩展使用 Select-Object 如何导致非自定义对象丢失吗?一直在寻求提高我的知识。
    • 使用Select-Object -Property ... 创建[pscustomobject] 类型的“property-bag”对象(b)(显然)与输入对象的类型不同,(b)具有静态副本 输入对象的属性,并且 (c) 缺少输入对象上存在的任何非属性成员,尤其是方法。
    猜你喜欢
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2021-10-05
    • 2019-11-17
    • 1970-01-01
    相关资源
    最近更新 更多