【问题标题】:Filtering sections of data including the starting and ending lines- PowerShell过滤数据部分,包括开始行和结束行 - PowerShell
【发布时间】:2016-10-25 11:56:23
【问题描述】:

我有一个如下所示的文本文件:

Data I'm NOT looking for  
More data that doesn't matter  
Even more data that I don't

&Start/Finally the data I'm looking for  
&Data/More data that I need  
&Stop/I need this too  

&Start/Second batch of data I need  
&Data/I need this too 
&Stop/Okay now I'm done  
Ending that I don't need  

输出需要如下:

文件1.txt

&Start/Finally the data I'm looking for  
&Data/More data that I need   
&Stop/I need this too  

文件2.txt

&Start/Second batch of data I need  
&Data/I need this too 
&Stop/Okay now I'm done  

我需要对文件夹中的每个文件执行此操作(有时会有多个文件需要过滤。)文件名可以递增:例如。文件1.txt、文件2.txt、文件3.txt。

这是我没有运气的尝试:

ForEach-Object{
$text -join "`n" -split '(?ms)(?=^&START)' -match '^&START' | 
Out-File B:\PowerShell\$filename}

谢谢!

【问题讨论】:

    标签: powershell powershell-4.0


    【解决方案1】:

    看起来您非常接近:您的代码正确提取了感兴趣的段落,但是缺少非&-起始行的段落内过滤,您需要写入段落特定 输出文件:

    $text -join "`n" -split '(?m)(?=^&Start)' -match '^&Start' | 
      ForEach-Object { $ndx=0 } { $_ -split '\n' -match '^&' | Out-File "File$((++$ndx)).txt" }
    

    这会为每个感兴趣的段落创建以File1.txt 开头的按顺序编号的文件。


    要对文件夹中的每个文件执行此操作,输出文件名使用固定命名方案 File<n> 跨越所有输入文件(因此累积编号):

    Get-ChildItem -File . | ForEach-Object -Begin { $ndx=0 } -Process {
      (Get-Content -Raw $_) -split '(?m)(?=^&Start)' -match '^&Start' | 
        ForEach-Object { $_ -split '\n' -match '^&' | Out-File "File$((++$ndx)).txt" }
    }
    

    为文件夹中的每个文件执行此操作,输出文件名基于输入文件名和每个输入文件的编号(PSv4+,由于使用-PipelineVariable):

    Get-ChildItem -File . -PipelineVariable File | ForEach-Object {
     (Get-Content -Raw $_) -split '(?m)(?=^&Start)' -match '^&Start' | 
      ForEach-Object {$ndx=0} { $_ -split '\n' -match '^&' | Out-File "$($File.Name)$((++$ndx)).txt" }
    }
    

    【讨论】:

      【解决方案2】:

      您发布了第二个问题(违反规则),它已被删除,但这是我的快速回答。我希望它能帮助你,让你更了解 PS 的工作原理:

      $InputFile = "C:\temp\test\New folder (3)\File1.txt"
      
      # get file content
      $a=Get-Content $InputFile
      
      # loop for every line in range 2 to last but one
      for ($i=1; $i -lt ($a.count-1); $i++)
          {
          #geting string part between & and / , and construct output file name
          $OutFile = "$(Split-Path $InputFile)\$(($a[$i] -split '/')[0] -replace '&','').txt"
      
          $a[0]| Out-File $OutFile #creating output file and write first line in it
          $a[$i]| Out-File $OutFile -Append #write info line
          $a[-1]| Out-File $OutFile -Append #write last line
          }
      

      【讨论】:

      • 我不知道在这个论坛上发布多个问题是违反规则的。对不起。
      • 将问题听起来像“我有苹果​​,想要馅饼”是违反规则的。您需要更详细地添加代码并提出更具体而不是一般性的问题。
      • 上述代码有效,但不会输入文本文件的最后一行。
      • 如果答案有帮助,请投票。您的第二个问题的语法是正确的 - 如何拆分小文件。您也可以轻松地将其更改为适合您。
      【解决方案3】:

      这样的?

       $i=0
       gci -path "C:\temp\ExplodeDir" -file | %{ (get-content -path $_.FullName -Raw).Replace("`r`n`r`n", ";").Replace("`r`n", "~").Split(";") | %{if ($_ -like "*Start*") {$i++; ($_ -split "~") | out-file "C:\temp\ResultFile\File$i.txt" }} }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-29
        • 2020-03-04
        • 1970-01-01
        • 2012-04-20
        相关资源
        最近更新 更多