PowerShell normal ifade mücadeleleri

Oct 16 2020

Bu benim ilk yazım, ihtiyacım olanı diğer yazıları okuyarak ve araştırarak bulma eğilimindeyim ama bu beni mağlup etti. Bir metin dosyasındaki verileri aramak için Powershell'de normal bir ifade kullanmaya çalışıyorum.

Örnek metin dosyası: (Örnek metin dosyasında o satırın sonuna kadar boşluklar vardır)

 Impression            CONCLUSION:                                                                     
 Impression                        
            
 Impression            CONCLUSION:                                                                     
 Impression            SomeData

 Impression            CONCLUSION:                                                                     
 Impression            SomeOtherData

 Impression            CONCLUSION:                                                                     
 Impression                                         

Sonuç satırından sonra ikinci satırın nerede boş olduğunu bulmaya çalışıyorum.

Basit girişimimin temeli buydu:

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 ile herhangi bir şeyin herhangi bir sonuç döndürmeyeceğini buldum. Hem \ r hem \ n'yi kendi başlarına denedim, İçeriği Ham olarak almaya çalıştım, ancak bu yalnızca tüm dosyanın çıktısını veriyor. Yardım için minnettarız, teşekkürler.

Güncelleme: Herkesin yanıtları için teşekkürler, boş olan sonuçtan sonra satırları bulmaya çalıştığımı belirtmeliydim. Get-Content -Raw kullanarak yeni başlayanlar için çalışmak için bir sayım aldım. Örnek verilerim, gösterim kelimesini içeren başka bir boş satır eklemek için biraz değişti: Ad / Yer Gösterim SONUÇ:
Gösterim Gösterim

Bu kod bana bir sayım kazandırdı: (başka bir forum gönderisinden çekildi / değiştirildi, bununla geldiğim için kredi almam)

$ search_string = "\ s SONUÇ: \ s \ r \ n \ s Gösterim \ s \ r \ n \ s Gösterim \ s \ r \ n \ s Gösterim \ s \ r \ n" $ file_path = "C: \ temp \ Log \ Conclusion.txt "$string = (Get-Content -raw -Path $dosya_yolu | Dize Seç$search_string -AllMatches | % { $_.matches}). sayı

Hala Raw kullanmadığımda işe yarayacak bazı daha fazla veriyi yazdırmanın bir yolu üzerinde çalışıyorum, sonucun yukarısındaki satırı yakalamak için bağlam kullanmayı planlamıştım, ancak raw her şeyi tek bir satırda topladığından bu işe yaramıyor. Yardım için tekrar teşekkürler. Raw'ı kullanıp kullanmama konusunda \ r \ n hakkında başka ipucu olan varsa lütfen bana bildirin.

Yanıtlar

paddywan Oct 16 2020 at 20:50

Bunun powershell ile ne kadar iyi çalışacağından emin değilim, ancak şuna bir şans verin: (*CRLF)CONCLUSION:\sImpression\s\s

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

Brian Oct 16 2020 at 21:46

İşte benim çirkin kaba kuvvet saldırım:

$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
postanote Oct 17 2020 at 23:16

Neden bunu yapmıyorsun?

# 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
#>

Açıklama:

  • ^ dize bağlantısının başlangıcıdır.
  • $, dize çapasının sonudur.
  • \ s, boşluk karakter sınıfıdır.
  • sıfır veya daha fazla tekrarıdır.
KeithMiller Oct 17 2020 at 04:25

Hala tam olarak ne yakalamak istediğinizden emin değilim, tamamen boş satırlar veya ardında Impressionveri bulunmayanlar.

Ancak belgeye göre Get-Contnet :

  • Dosyalar için içerik her seferinde bir satır okunur ve her biri bir içerik satırını temsil eden bir nesne koleksiyonu döndürür.

Öyleyse <newline>karakterler bir dizge dizisinin öğe ayırıcıları olarak "tüketilir".
Deneyin:

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

böylece a <newline>ile asla yazıldığı gibi eşleşmezsiniz .

-RawDosyayı <newline>karakter içeren tek bir uzun dize olarak ele almak veya bir diziyi aramak için mantığınızı yeniden yazmak için parametreyi kullanabilirsiniz .


Ayrıca, Select-string dokümantasyonu, bir dosyayı doğrudan alıp satır satır işleyebileceğini, buna gerek kalmadan gösterir Get-Content.


Güncelleme

Hâlâ hangi satırın çıktısını almak istediğinizden emin değilim, ancak burada istediğini düşündüğüm şeyin iskelet bir örneği var . Varsayımlarım:

  • Aradığınız satırlar "Gösterim" in ardından metin içermeyen satırlardır (Lütfen bunun gerçek mi yoksa veri mi olduğunu belirtin)
  • Bir eşleşme bulunduğunda, önceki satır çıktı dosyası için alınır.
$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