PowerShell 正则表达式难题

PowerShell 正则表达式难题

这是我的第一篇文章,我倾向于通过阅读和搜索其他文章来找到我需要的内容,但这篇文章让我失败了。我试图在 Powershell 中使用正则表达式在文本文件中查找数据。

示例文本文件:(示例文本文件中直到该行末尾都有空格)

 Impression            CONCLUSION:                                                                     
 Impression                        
            
 Impression            CONCLUSION:                                                                     
 Impression            SomeData

 Impression            CONCLUSION:                                                                     
 Impression            SomeOtherData

 Impression            CONCLUSION:                                                                     
 Impression                                         

我正在寻找结论行之后第二行空白的位置。

这是我简单尝试的基础:

Get-Content -Path "C:\temp\Log\Conclusion.txt" | Select-String -Pattern "CONCLUSION:\s*\r\n\s*Impression\s*\r\n\s*Impression" -Context 1, 1

我发现任何带有 \r\n 的内容都不会返回任何结果。我尝试了 \r 和 \n,并尝试将内容作为原始内容获取,但这只会再次输出整个文件。非常感谢您的帮助,谢谢。

更新:感谢大家的回复,我应该明确说明我试图找到结论之后的空行。我最终使用 Get-Content -Raw 获得了一个计数,以便初学者使用。我的样本数据略有变化,添加了另一个带有单词印象的空白行:名称/位置印象结论:
印象印象

此代码可以让我进行计数:(从另一个论坛帖子中提取/修改,我不承担提出此想法的荣誉)

$search_string = "\s结论:\s\r\n\s印象\r\n\s印象\r\n\s印象\r\n“$file_path = “C:\temp\Log\Conclusion.txt”$string = (Get-Content -raw -Path $file_path | Select-String $search_string -AllMatches | % { $_.matches}).count

我仍在研究一种打印更多数据的方法,这种方法只有在不使用 Raw 时才有效,我原本计划使用 context 来抓取结论上方的行,但由于 raw 将所有内容放在一行中,所以这种方法行不通。再次感谢您的帮助,如果有人有更多关于能够使用 \r\n 而不使用 Raw 的提示,请告诉我。

答案1

我不确定这与 powershell 配合得如何,但可以尝试一下: (*CRLF)CONCLUSION:\sImpression\s\s

https://regex101.com/r/d6Pm2k/1

答案2

以下是我拙劣的暴力攻击:

$blankRows = @()
$targetRows = @()
$rowNum = 0
$foundRows = @()

$myFile = Get-Content $thisFile

Foreach($thisRow in $myFile){
    $rowNum++
    if($thisRow -eq "Impression"){$blankRows += $rowNum}
    if ($thisRow -match 'CONCLUSION'){$targetRows += $rowNum}
}

Foreach($blrw in $blankRows){
    if ($targetRows -contains ($blrw-1)){$foundRows += $blrw}

}

$foundRows

答案3

为什么不这样做呢?

# Create some sample data file
@'
Impression CONCLUSION:
Impression

Impression CONCLUSION:
Impression SomeData

Impression CONCLUSION:
Impression SomeOtherData

Impression CONCLUSION:
Impression
'@ | 
Out-File -FilePath 'D:\Temp\Imprestion.txt' -Force
Get-Content -Path 'D:\Temp\Imprestion.txt'
# Results
<#
Impression CONCLUSION:
Impression

Impression CONCLUSION:
Impression SomeData

Impression CONCLUSION:
Impression SomeOtherData

Impression CONCLUSION:
Impression
#>

# Import the sample data file as a CSV, use the space as a Delimiter
Import-Csv -Path 'D:\Temp\Imprestion.txt' -Delimiter ' ' -Header Property, Value
# Results
<#
Property   Value        
--------   -----        
Impression CONCLUSION:  
Impression              
Impression CONCLUSION:  
Impression SomeData     
Impression CONCLUSION:  
Impression SomeOtherData
Impression CONCLUSION:  
Impression              
#>

# Filter by the Value property
Import-Csv -Path 'D:\Temp\Imprestion.txt' -Delimiter ' ' -Header Property, Value | 
Where-Object -Property Value -EQ $null
# Results
<#
Property   Value
--------   -----
Impression      
Impression  
#>

# Using Select-String and a RegEx 'Not Match'
Select-String -Path 'D:\Temp\Imprestion.txt' -Pattern '^((?!Impression [a-zA-Z]).)*$'
# Results
<#
D:\Temp\Imprestion.txt:2:Impression
D:\Temp\Imprestion.txt:3:
D:\Temp\Imprestion.txt:6:
D:\Temp\Imprestion.txt:9:
D:\Temp\Imprestion.txt:11:Impression
#>

# Using Select-String and RegEx match
Select-String -Path 'D:\Temp\Imprestion.txt' -Pattern '^Impression\s*$'
# Results
<#
D:\Temp\Imprestion.txt:2:Impression
D:\Temp\Imprestion.txt:11:Impression
#>

解释:

  • ^ 是字符串锚点的开头。
  • $ 是字符串锚点的结尾。
  • \s 是空白字符类。
  • 是零次或多次重复。

答案4

我仍然不确定您到底想捕获什么,完全空白的行还是带有Impression且没有后续数据的行。

但根据文件,获取内容

  • 对于文件来说,每次读取一行内容并返回一个对象集合,每个对象代表一行内容。

因此,<newline>字符被“用作”字符串数组的元素分隔符。
尝试:

Get-Content -Path "C:\temp\Log\Conclusion.txt" | gm
(Get-Content -Path "C:\temp\Log\Conclusion.txt").Count

因此您永远不会将 a<newline>与所写的代码相匹配。

您可以使用-Raw参数将文件视为一个带有<newline>字符的长字符串,或者重写搜索数组的逻辑。


此外,选择字符串表明它可以直接获取文件并逐行处理,而不需要Get-Content


更新

我仍然不确定你想输出哪一行,但这是我的骨架样本思考你问的。我的假设是:

  • 您要查找的是“印象”后面没有文本的行(请说明这是文字还是数据)
  • 当找到匹配项时,将捕获前一行作为输出文件。
$File = Get-Content -Path "C:\temp\Log\Conclusion.txt"
$OutLines   = @()
$EmptyMatch = '^Impression\s*$'
$i = 0
ForEach ( $line in $File ) {
    If ( $line -match $EmptyMatch ) {
        $OutLines += $File[ $i - 1 ]
    }
    $i++
}
$OutLines | Set-Content 'c:\MyStuff\OutFile.txt'
Add

相关内容