这是我的第一篇文章,我倾向于通过阅读和搜索其他文章来找到我需要的内容,但这篇文章让我失败了。我试图在 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
答案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