【问题标题】:Need a way to write the remaining data of file after finding a string in Poweshell在 Poweshell 中找到字符串后需要一种方法来写入文件的剩余数据
【发布时间】:2021-08-01 17:50:58
【问题描述】:

我有一个大文件(250 Gb),我需要搜索一个字符串,一旦找到它,我需要从该行复制所有内容到文件末尾。 示例文件:

Bird
Lion
Tiger
Jaguar
Frog
Snake

结果是:

Jaguar
Frog
Snake

我是 PowerShell 新手,尝试过以下操作,但只是找到字符串 Jaguar 并将其打印出来,我还需要以下几行。

Get-Content -Path "C:\Dump\test1.txt" |
Select-String 'Jaguar' |
Set-Content -Path "C:\Dump\test2.txt"

【问题讨论】:

  • 您是在寻找完全匹配的词还是该词可以包含或与其他词连接?
  • 完全匹配。

标签: powershell


【解决方案1】:

既然你说你的文件真的很大(而且可能生成的文件也很大),我想我会使用 switch 和 StreamWriter

$writer  = [System.IO.StreamWriter]::new('C:\Dump\test2.txt')
$foundMarker = $false
switch -Regex -File 'C:\Dump\test1.txt' {
    '\bJaguar\b' { $foundMarker = $true; $writer.WriteLine($_) }
    default { if ($foundMarker) { $writer.WriteLine($_) } }
}
# clean up
$writer.Flush()
$writer.Dispose()

\b 包围您的关键字 Jaguar 使其成为“全词”搜索。

附:如果需要关键字区分大小写匹配,请在开关后添加开关CaseSensitiveswitch -Regex -CaseSensitive -File 'C:\Dump\test1.txt' {...}

【讨论】:

  • 做得很好。请注意,调用.Dispose()(或.Close()隐式会刷新,所以我认为您不需要显式调用.Flush()
【解决方案2】:

我创建了一个简单的 unstable 函数,可用于处理大文件:

function Get-Content-Since-Equals-To-File(){
    param (
        [string] $Path,        
        [string] $LineText,
        [string] $PathNewFile
    )
    $writer  = [System.IO.StreamWriter]::new($PathNewFile)
    $continue=0
    foreach($line in [System.IO.File]::ReadLines($Path))
    {    
        if($line.Equals($LineText)){$continue=1}
        if( $continue -eq 1){
            #Add-Content -Path $PathNewFile -Value $line #According to  mklement0 using Add-Content is really slow
            $writer.WriteLine($line);
        }
    }
    $writer.Dispose();    
}

然后您可以通过传递文件路径来调用该函数,因为您想要获取文件的单词和新文件路径:

Get-Content-Since-Equals-To-File -Path ./1.txt "Jaguar" -PathNewFile './newFile.txt'

上面的结果生成了一个具有所需结果的文件(注意我以相对路径为例,在您的日常工作中,您应该使用绝对路径并考虑工作目录,即 cwd):

Get-Content ./newFile.txt
Jaguar
Frog
Snake

这个函数是基于Read file line by line in PowerShell,因为它是逐行读取的,你可以在大文件中使用它。

如果不需要匹配,可以使用其他条件来适配功能。

感谢 @mkelement0 对 Add-Content 的改进,我使用 StreamWriter 更新了代码。

【讨论】:

  • 感谢更新。您可以通过将[System.IO.StreamWriter]::new($PathNewFile) 替换为[System.IO.StreamWriter]::new((Convert-Path -LiteralPath $PathNewFile)) 来解决相对路径问题。此外,最好使用[bool] 值来表示布尔值:$continue = $false / $continue = $trueif ($continue) ...
猜你喜欢
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 2011-03-05
  • 2015-07-06
  • 2021-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多