扫描 txt 文件中的多个字符串并保存以下行

Scan txt file for multiple strings and save the following lines

我有一个问题想解决,但是,由于我不具备 PowerShell 知识,事实证明它比我希望的要难。所以任何帮助将不胜感激。

问题可以简化为:

  1. 在 txt 文件中查找字符串

  2. 提取该字符串后行的信息

  3. 将信息存储在句柄中

  4. 在 txt 文件中找到第二个字符串并重复该过程

  5. 将两个字符串都存储在一个新文件中或删除 txt 文件中的所有其他内容。

然后我尝试对大约 20k 个文件执行此操作。我希望在他们的关键字和逗号分隔下有信息,以便我可以将它们导入其他系统。

我的文件看起来有点像下面这样

random words 
that are unimportant 
Keyword
FirstlineofNumbersthatIwanttoExtract
random words again that are unimportant 
Secondkeyword
SecondLineOfNumbersThatIWantToExtract
end of the file 

然而,就我要提取的行所在的行而言,所有文件都不相似。我希望输出类似于

Keyword, SecondKeyword
FirstLineOfNumbersThatIWantToExtract, SecondLineOfNumbersThatIWantToExtract

完成了。我走到这一步

 [System.IO.DirectoryInfo]$folder = 'C:\users\xx\Desktop\mappcent3'

 foreach ($file in ($folder.EnumerateFiles())) {
     if ($file.Extension -eq '.txt') {

         $content = Get-Content $file

         $FirstRegex = 'KeyWordOne
    (.+)$'

    $First_output = ""
    $test = Select-String -Path $file.FullName -Pattern $FirstRegex 

  }
}

这将执行类似于您所要求的操作。这需要 PowerShell 3.0+

$path = 'C:\users\xx\Desktop\mappcent3'
$firstKeyword = "Keyword"
$secondKeyword = "Secondkeyword"
$resultsPath = "C:\Temp\results.csv"
Get-ChildItem $path -Filter "*.txt" | ForEach-Object{
    # Read the file in
    $fileContents = Get-Content $_.FullName

    # Find the first keyword data
    $firstKeywordData = ($fileContents | Select-String -Pattern $firstKeyword -Context 0,1 -SimpleMatch).Context.PostContext[0]

    # Find the second keyword data
    $secondKeywordData = ($fileContents | Select-String -Pattern $secondKeyword -Context 0,1 -SimpleMatch).Context.PostContext[0]

    # Create a new object with details gathered. 
    [pscustomobject][ordered]@{
        File = $_.FullName
        FirstKeywordData = $firstKeywordData
        SecondKeywordData = $secondKeywordData
    }

} | Export-CSV $resultsPath -NoTypeInformation

Select-String 是这里最神奇的地方。我们利用 -Context 消耗匹配前后的行。我们想要下面的一个,所以这就是我们使用 0,1 的原因。将其包装在自定义对象中,然后我们可以将其导出到 CSV 文件。

关键字重叠

请注意,您的关键字可能会重叠并在输出文件中产生奇怪的结果。在您的示例中,关键字匹配多行,因此结果集会反映出来。


如果您只是想写回原始文件,您也可以轻松地做到这一点

"$firstKeywordData,$secondKeywordData" | Set-Content $_.FullName

或类似的东西。

Select-String cmdlet 有一个 -Context 参数,可以轻松提取匹配行之前或之后的行。

您可以使用 Export-Csv 导出您需要的格式(尽管对于 20K 的文件您可能希望直接写入输出文件)

foreach($file in Get-ChildItem C:\users\xx\Desktop\mappcent3 |Where {-not $_.PsIsContainer})
{
    $FirstKeyword = 'FirstKeyword'
    $FirstLine = Select-String -Path $file.FullName -Pattern $FirstKeyword -Context 0,1 |Select -Expand Context -First 1 |Select -Expand PostContext
    $SecondKeyword = 'SecondKeyword'
    $SecondLine = Select-String -Path $file.FullName -Pattern $SecondKeyword -Context 0,1 |Select -Expand Context -First 1 |Select -Expand PostContext

    New-Object psobject -Property @{$FirstKeyword=$FirstLine;$SecondKeyword=$SecondLine} |Export-Csv (Join-Path $file.DirectoryName ($file.BaseName + '_keywords.txt'))
}