【问题标题】:Removing Headers from CSV in Powershell在 Powershell 中从 CSV 中删除标头
【发布时间】:2019-12-26 02:39:01
【问题描述】:

需要帮助从 CSV 文件中删除标题。导入文件的工具有非常严格的要求。第一行必须是 Title,然后是第 2 行 日期:8/19/2019。第三行应该包含没有标题的数据。

尝试将其导入回来并使用 [1..-1] 表示法删除第一行,并尝试使用 Select-object -skip 1 引入数据。还是不行。

还尝试将对象数组写入 TXT,但它仅作为字段出现,而不是像在 CSV 中那样基于选项卡。示例:

日期: 信息: 字段1:

get-content "c:\users\user123\documents\adh\_$(get-date (get-date).addDays($i) -f yyyy-MM-dd).csv" | Select-Object -Skip 1 | Set-Content "c:\users\user123\documents\adh\_$(get-date (get-date).addDays($i) -f yyyy-MM-dd).txt" 

即使在我尝试删除它们之后,该文件仍然包含标题。

【问题讨论】:

  • 你可以选择一个答案吗?

标签: powershell csv header export-csv


【解决方案1】:

将文件复制到测试环境中,尝试添加-NoTypeInformation这样可能会解决你的问题。

-NoTypeInformation 会删除元数据,所以在测试时要小心。

【讨论】:

  • 我认为-NoTypeInformation 只是在导出 CSV 时删除了该类型标题。我认为它对实际的 CSV 标头没有任何作用。不过我可能是错的
【解决方案2】:

我能够通过像这样生成测试 CSV 来重现您的问题:

Get-Process | Select ProcessName, ID, SI | Export-CSV C:\temp\test.csv -NoTypeInformation

您偶然发现了管道的一个有趣方面。我不知道为什么它正在做它正在做的事情的细节,但你有两种方法可以自动将标题放回 CSV:

  1. 将 -NoClobber 添加到您的输出文件: Get-Content C:\temp\test.csv | Select -Skip 1 | Out-File -FilePath "C:\temp\new.csv" -NoClobber 这里需要注意的是,它不会让您覆盖使用 Get-Content 打开的文件,因此您必须将其发送到单独的文件中
  2. 或者您可以通过将Get-Content C:\temp\test.csv | Select -Skip 1 的结果存储到一个变量中然后将该变量发送到一个常规的Out-File 调用来绕过管道。这会让你覆盖文件。

【讨论】:

  • 听起来你认为 OP 的问题是试图写回正在读取的同一个文件 - 它不是,因为问题中的命令写入 不同 i> 文件 (*.txt)。至于为什么:管道streams(逐个对象处理输入),所以写命令尝试将行写入仍然打开的文件,因为读命令( Get-Content) 还没有读完。一个简单的解决方法是将Get-Content 调用包含在(...) 中,这会强制预先读取:(Get-Content ...) | ... | Set-Content ...。不过,数据丢失的风险很小。
【解决方案3】:

获得包含字段头记录的 .csv 文件后,即可构建该文件。 csmem.csv 文件已生成,但有一个标题记录。这将在前两 (2) 条记录上写入标题和日期,然后附加不带标题记录的 .csv 文件。

"The Title" | Out-File -FilePath "C:\src\t\sf.csv" -Encoding ascii
(Get-Date).ToString('yyyy-MM-dd') | Out-File -FilePath "C:\src\t\sf.csv" -Encoding ascii -Append
Get-Content -Path 'C:\src\t\csmem.csv' |
    Select-Object -Skip 1 |
    Out-File -FilePath "C:\src\t\sf.csv" -Encoding ascii -Append

【讨论】:

    【解决方案4】:

    给定一个生成的示例文件:

    > Get-Content .\_2019-08-19.csv
    "COLA","ColB"
    "Test1","Foo"
    "Test2","Baz"
    "Test3","Bar"
    "Test4","Baz"
    "Test5","Baz"
    

    这个脚本:

    ## Q:\Test\2019\08\20\SO_SO_57581085.ps1
    ## 
    $i = 1
    $BaseDir = 'C:\Users\user123\Documents\adh'
    # $BaseDir = (gi .).FullName
    $BaseName= '_{0:yyyy-MM-dd}' -f (Get-Date).AddDays(-$i)
    
    "Your Title`ndate: {0:M\/d\/yyyy}" -f (Get-Date).AddDays(-$i) | 
      Set-Content (Join-Path $BaseDir ($BaseName+'.txt')) # -Encoding if req.
    
    Get-Content (Join-Path $BaseDir ($BaseName+'.csv')) | 
      Select-Object -Skip 1 | 
        Add-Content (Join-Path $BaseDir ($BaseName+'.txt')) # -Encoding if req.
    

    产生这个结果文件:

    > Get-Content .\_2019-08-19.txt
    Your Title
    date: 8/19/2019
    "Test1","Foo"
    "Test2","Baz"
    "Test3","Bar"
    "Test4","Baz"
    "Test5","Baz"
    

    【讨论】:

      【解决方案5】:

      听起来您的起点是一个内存中的对象数组,要转换为不带标题的CSV。

      要获得没有标题的 CSV 表示,您无需使用Export-Csv 创建中间文件 - 只需通过管道连接到ConvertTo-Csv,它会生成一个字符串数组,其第一个元素 - 标题行 - 您可以使用 Select-Object -Skip 1 跳过。

      因此,您的整个文件可以通过一个可扩展的此处字符串写入:

      # Format the date string.
      $i = 2 # sample value
      $dateString = '{0:yyyy-MM-dd}' -f (Get-Date).AddDays($i)
      
      # The input object array
      # $objArray = ...
      
      # Use an expandable here-string to write the output file.
      @"
      Title
      $dateString
      $($objArray | ConvertTo-Csv | Select-Object -Skip 1 | Out-String)
      "@ | Set-Content -NoNewline "c:\users\user123\documents\adh\_$dateString.txt" 
      

      至于你尝试了什么

      尝试使用 [1..-1] 表示法将其导入并删除第一行

      [1..-1] not 在 PowerShell 中跳过数组的第一个元素,因为 1..-1 是一个 范围表达式,它扩展为以下索引列表:@ 987654327@;也就是说,您要提取的正是 3 个元素:第二个 (1)、第一个 (0) 和最后一个 (-1)。

      还尝试将对象数组写入 TXT,但它仅作为字段出现,而不是像在 CSV 中那样基于选项卡。示例:

      听起来您将内存中的对象数组发送到 *.txt 文件时使用的是 other 而不是 Export-Csv,这不会为您提供 CSV 输出;听起来您使用了>Out-File,其中对象的格式与它们打印到控制台的方式相同,这是一种 for-display 格式,不适合编程处理。

      get-content ....csv | Select-Object -Skip 1 | Set-Content ....txt

      假设输入*.csv 文件是使用
      Export-Csv -NoTypeInformation 创建的,那么该命令应该 起作用。

      如果你没有使用-NoTypeInformation,则使用-Skip 2,即跳过一个附加行,从而跳过@的type-annotation line 987654340@ - 不幸的是 - 默认输出为第一行。

      注意:Windows PowerShellExport-Csv 的这种违反直觉的默认行为已在 PowerShell Core 中得到修复。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多