【问题标题】:Remove header from delimited text file从分隔的文本文件中删除标题
【发布时间】:2017-08-22 18:59:20
【问题描述】:

我有文本文件,其中数据由正斜杠分隔。将其导入自定义对象并提供给自定义对象很容易,但文件的标题包含分隔符。示例如下:

标题行 1/INFO/MOREINFO 标题行 2/INFO/MOREINFO 标题行 3/INFO/MOREINFO 标题行 4/INFO/MOREINFO 标题行 5/INFO/MOREINFO 标题行 6/INFO/MOREINFO 标题 7/INFO/MOREINFO LINE1A/1B///1E/1F/1G/1H LINE2A/2B/2C//2E//2G/2H ... /结尾/

“LINE1A”、“LINE1B”等行有我需要导入的数据。使用 -split '/' 可以让我将所有内容拆分为一个不错的数组,但前提是该标题不存在。

$data = (Get-Content text.txt).Replace('Line', '/Line') -split('/')

如果存在标头,$data 数组中的第一个元素包括标头。

我尝试过字符串操作技巧,但不幸的是,标题文本从一个文件到下一个文件不一致。行数(始终为 7)和斜线数(每个标题行 2 个)是一致的,但每行中的文本各不相同。

由于Get-Content 将数组拆分为回车(如果我错了,请纠正我),我虽然可以删除前 7 个数组元素。此代码用于删除第一个元素:

$data = (Get-Content text.txt) 
$data = $data | Where-Object {$_ -ne $data[0]}

但它的可扩展性不是很好。我不想循环命令 7 次。有没有更优雅的方法来做到这一点?也许一些基于回车和/或斜杠的正则表达式?

【问题讨论】:

    标签: powershell text csv


    【解决方案1】:

    这里很简单,使用 Select-Object cmdlet 跳过前 7 行!

    $data = (Get-Content text.txt | Select -Skip 7).replace('Line','/Line') -split('/')
    

    如果第 8 行有空行,您可能希望跳过前 8 行。

    【讨论】:

    • 可能还要处理最后一行。
    • 他说如果他没有标题行,他的流程就可以工作,所以我认为可以安全地假设他已经有一些事情要处理最后一行。
    • 谢谢。我知道这会很简单。
    【解决方案2】:

    将文件读入数组 $data 后,只需将除前 7 行之外的所有数据复制到新数组中

     $data2 = $data[7..($data.length-1)]
    

    然后使用$data2

    【讨论】:

      【解决方案3】:

      如果数字和线条不可信,我会提供其他内容。让我们过滤掉所有以 header 或 end 开头的行并过滤空行。然后让我们像Import-CSV 那样创建自定义对象

      $fileContents = Get-Content "file"
      $csv = $fileContents | Where-Object{![string]::IsNullOrWhiteSpace($_) -and $_ -notmatch "^(HEADER|/END/)"}
      # Determine the number of headers from the file 'CSV' line
      $numberOfHeaders = $csv[0].split("/").Count
      ConvertFrom-Csv $csv -Header (1..$numberOfHeaders|ForEach-Object{"LINE $_"}) -Delimiter "/"
      

      这仅使用您的示例输入数据而忽略省略号。因此,现在您拥有与使用 IMport-CSV 时正确的 CSV 相同的外观。标题是我猜的。如果出现其他需求,不需要太多改变。

      LINE 1 LINE 2 LINE 3 LINE 4 LINE 5 LINE 6 LINE 7 LINE 8
      ------ ------ ------ ------ ------ ------ ------ ------
      1A     1B                   1E     1F     1G     1H    
      2A     2B     2C            2E            2G     2H    
      

      如果您不需要数据上的前导“LINE”,那么一个简单的管道会在转换之前解决这个问题

      ForEach-Object{$_ -replace "^LINE"}
      

      如果您想从标题中删除它,请使用此1..$numberOfHeaders|ForEach-Object{"LINE $_"}。因此,如果您对仅编号的列感到满意,则可以将其保留在 1..$numberOfHeaders

      【讨论】:

        猜你喜欢
        • 2019-05-15
        • 1970-01-01
        • 1970-01-01
        • 2013-08-06
        • 1970-01-01
        • 2021-05-18
        • 2020-03-28
        • 2012-09-24
        • 1970-01-01
        相关资源
        最近更新 更多