Проблемы с регулярными выражениями 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
Я обнаружил, что Anything with \ r \ n не вернет никаких результатов. Я попробовал как \ r, так и \ n по отдельности, я попытался получить контент как Raw, но это просто снова выводит весь файл. Помощь приветствуется, спасибо.
Обновление: спасибо за все ответы, я должен был указать, что пытался найти пустые строки после вывода. Я закончил тем, что начал работать с счетчиком с помощью Get-Content -Raw. Мои выборочные данные немного изменить , чтобы добавить еще одну пустую строку со словом впечатление: Имя / Расположение Impression ВЫВОД:
Impression Impression
Этот код позволил мне подсчитать: (извлечено / изменено из другого сообщения на форуме, я не беру на себя ответственность за это)
$ search_string = "\ s ВЫВОД: \ s \ r \ n \ s Впечатление \ s \ r \ n \ s Впечатление \ s \ r \ n \ s Впечатление \ s \ r \ n" $ file_path = "C: \ temp \ Log \ Conclusion.txt "$string = (Get-Content -raw -Path $file_path | Выбрать строку$search_string -AllMatches | % { $_.matches}). count
Я все еще работаю над способом распечатать еще несколько данных, которые будут работать только без использования Raw, я планировал использовать контекст, чтобы захватить строку выше вывода, но, поскольку raw объединяет все в одну строку, это не работает. Еще раз спасибо за помощь, если у кого-то есть еще советы о том, как можно использовать \ r \ n и не использовать Raw, дайте мне знать.
Ответы
Я не уверен, насколько хорошо это будет работать с PowerShell, но попробуйте: (*CRLF)CONCLUSION:\sImpression\s\s
https://regex101.com/r/d6Pm2k/1
Вот моя уродливая атака грубой силой:
$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
Почему бы просто не сделать это?
# 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 - это класс символов пробела.
- - это ноль или более повторений.
Я до сих пор не совсем уверен, что именно вы хотите записать: полностью пустые строки или строки, за которыми Impressionне следуют данные.
Но согласно документации Get-Contnet :
- Для файлов содержимое считывается по одной строке за раз и возвращает набор объектов, каждый из которых представляет собой строку содержимого.
ТАК <newline>символы "потребляются" как разделители элементов строкового массива.
Пытаться:
Get-Content -Path "C:\temp\Log\Conclusion.txt" | gm
(Get-Content -Path "C:\temp\Log\Conclusion.txt").Count
так что вы никогда не сопоставите a <newline>с написанным кодом.
Вы можете использовать -Rawпараметр, чтобы рассматривать файл как одну длинную строку с <newline>символами или переписать логику поиска в массиве.
Кроме того, документация для Select-string показывает, что он может напрямую брать файл и обрабатывать его построчно, без необходимости Get-Content.
Обновить
Я все еще не уверен, какую строку вы хотите вывести, но вот скелетный образец того, что, я думаю, вы просите. Мои предположения:
- Строки, которые вы ищете, - это строки без текста после слова "Impression" (пожалуйста, поясните, является ли это буквальным или буквальным)
- Когда совпадение найдено, предыдущая строка захватывается для выходного файла.
$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