Adam de Automator

Eén van de eerste Linux commando’s die veel systeembeheerders leren is grep. Dit eerbiedwaardige gereedschap bestaat al tientallen jaren en is cruciaal voor de gereedschapskist van iedere systeembeheerder. De kern van grep is simpelweg de mogelijkheid om platte tekst te doorzoeken op een RegEx patroon. Grep kan bestanden in een bepaalde directory of gestreamde invoer doorzoeken om overeenkomsten te vinden. Wist je dat PowerShell grep heeft? Nou…bijna.

PowerShell, een taal, is meer dan alleen een binary voor één doel. Welke ingebouwde mogelijkheden zijn er om platte tekst te doorzoeken met RegEx patronen, zoals grep dat doet? In dit artikel verkennen we de talloze manieren om met PowerShell naar tekst in bestanden te zoeken.

Verkenning van het Select-String Cmdlet

Select-String (onze PowerShell grep) werkt op tekstregels en zoekt standaard naar de eerste overeenkomst in elke regel en geeft vervolgens de bestandsnaam, het regelnummer en de tekst in de gematchte regel weer. Bovendien kan Select-String werken met verschillende bestandscoderingen, zoals Unicode tekst, door gebruik te maken van het byte-order-mark (BOM) om het coderingsformaat te bepalen. Als de BOM ontbreekt, zal Select-String aannemen dat het een UTF8 bestand is.

Parameters van Select-String

  • AllMatches – Normaal gesproken zoekt Select-String alleen naar de eerste overeenkomst in elke regel, met deze parameter zoekt het cmdlet naar meer dan één overeenkomst. Een enkel MatchInfo object zal nog steeds worden uitgezonden voor elke regel, maar het zal alle gevonden overeenkomsten bevatten.
  • CaseSensitive – Matches zijn standaard niet hoofdlettergevoelig, dit dwingt het cmdlet om te zoeken naar overeenkomsten die exact overeenkomen met het invoer patroon.
  • Context – Een zeer nuttige parameter in die zin, dat je het aantal regels voor en na de match kunt definiëren die zullen worden weergegeven. Door deze parameter toe te voegen wordt het uitgezonden MatchInfo object zodanig gewijzigd dat het een nieuwe Context eigenschap bevat die de opgegeven regels bevat.

Bedenk dat als u de uitvoer van Select-String naar een andere Select-String oproep leidt, zal de context niet beschikbaar zijn omdat u alleen zoekt op de enkele resulterende MatchInfoline eigenschap.

  • Culture – Gebruikt met de SimpleMatch parameter, specificeert dit een cultuur die moet worden gematcht met het gespecificeerde patroon. Dit omvat opties zoals en-USes, of fr-FR als voorbeelden. Enkele andere nuttige opties zijn de Ordinal en Invariant opties. Ordinal is voor niet-linguïstische binaire vergelijkingen en Invariant is voor cultuuronafhankelijke vergelijkingen.

Deze parameter is geïntroduceerd in PowerShell 7 en is niet beschikbaar voor eerdere versies. Houd er ook rekening mee dat dit standaard de huidige cultuur van het systeem gebruikt, die kan worden gevonden met Get-Culture.

  • Encoding – Geef de codering op van het doelbestand waarnaar moet worden gezocht, die standaard utf8NoBOM.
    • ascii: Gebruikt de codering voor de ASCII (7-bits) tekenset.
    • bigendianunicode: Codeert in UTF-16-indeling met gebruik van de big-endian bytevolgorde.
    • oem: Gebruikt de standaardcodering voor MS-DOS en consoleprogramma’s.
    • unicode: Codeert in UTF-16-indeling met gebruik van de little-endian bytevolgorde.
    • utf7: codeert in UTF-7-formaat.
    • utf8: codeert in UTF-8-formaat.
    • utf8BOM: Encodeert in UTF-8 formaat met Byte Order Mark (BOM)
    • utf8NoBOM: Encodes in UTF-8 formaat zonder Byte Order Mark (BOM)
    • utf32: Encodes in UTF-32 formaat.

    Met ingang van PowerShell Core 6.2 accepteert de parameter Encoding ook numerieke ID’s van geregistreerde codepagina’s, zoals 1251 of tekenreeksnamen, zoals windows-1251.

Met ingang van PowerShell Core 6.2 accepteert de parameter Encoding ook numerieke ID’s van geregistreerde codepagina’s, zoals 1251 of tekenreeksnamen zoals windows-1251.

  • Exclude – Werk met de parameter Path, sluit specifieke items uit met behulp van een patroon, zoals *.txt.
  • Include – Net als de Exclude parameter, zal Include alleen de gespecificeerde items opnemen met gebruik van een patroon, zoals *.log.
  • List – Geeft alleen de eerste overeenkomstige tekst van elk invoerbestand. Dit is bedoeld als een snelle en efficiënte manier om een lijst op te vragen van bestanden met overeenkomende inhoud.
  • LiteralPath – Dit vertelt Select-String om de waarden als invoer te gebruiken, in plaats van waarden zoals * te interpreteren als een wildcard. Als het pad escape-tekens bevat, zet ze dan tussen enkele aanhalingstekens om geen interpretatie te doen.
  • NoEmphasis – In plaats van de string waarop het patroon matcht te accentueren, schakel je het accentueren van matches uit. Standaard gebruikt de accentuering negatieve kleuren, gebaseerd op de achtergrondkleuren van de tekst.
  • NotMatch – Zoek naar tekst die niet overeenkomt met het opgegeven patroon.
  • Path – Geef het pad op naar de te doorzoeken bestanden. Wildcards zijn toegestaan, maar u kunt niet alleen een directory opgeven. De standaardinstelling is de lokale directory.
  • Pattern – Het patroon om de invoerinhoud of bestanden te doorzoeken op basis van RegEx.
  • SimpleMatch – Gebruik een eenvoudige overeenkomst in plaats van reguliere expressies. Omdat RegEx niet wordt gebruikt, heeft het geretourneerde MatchInfo object geen waarden in de Matches eigenschap.
  • Raw – Uitvoer van de overeenkomende tekenreeksen, zonder een MatchInfo object. Dit is het gedrag dat het meest lijkt op grep en niet op de meer objectgeoriënteerde aard van PowerShell.
  • Quiet – Geeft alleen een $true of $false terug als het patroon is gevonden.

Het gebruik van PowerShell Grep err… Select-String

Weten hoe de parameters en opties van een cmdlet werken is natuurlijk niet helemaal hetzelfde als het gebruiken in een productie-omgeving. Laten we eens in de voorbeelden duiken en zien hoe we Select-String kunnen gebruiken om het vinden van tekstmatches te vergemakkelijken.

Er zijn drie manieren waarop we Select-String kunnen gebruiken om overeenkomsten te vinden.

  • Pipe in geciteerde tekst naar het Select-String cmdlet, d.w.z. stream de tekst in.
  • Gebruik de tekst die in een variabele is opgeslagen, geef de variabele door aan de InputObject parameter.
  • Gebruik de Path parameter om bestanden op te geven waar de tekst in moet worden gezocht.

De bestanden die we gebruiken om dit te testen zijn willekeurig gegenereerde inhoud, maar van hetzelfde type als vaak in productiesystemen wordt aangetroffen.

Eenvoudige overeenkomst in bestanden

Beginnen met een heel eenvoudig voorbeeld, laten we kijken naar Joe in een handvol CSV-bestanden.

Select-String -Path "Users\*.csv" -Pattern "Joe"
Demonstratie van een eenvoudige Select-String patroonmatch.
Demonstreer een eenvoudige Select-String patroonmatch.

Zoals je kunt zien is dit vrij eenvoudig, we zien hoe Joe wordt gemarkeerd op de regel met de rest van de gegevens. Maar welke gegevens worden hier eigenlijk teruggegeven? Laten we eens kijken naar alle eigenschappen van een geretourneerde overeenkomst.

Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object * -First 1
Weergave van de geretourneerde eigenschappen van een Select-String-overeenkomst.
Toont de geretourneerde eigenschappen van een Select-String-match.

We hebben hier een paar eigenschappen die nuttig zijn. Met name de linepathpattern, en matches. Het meeste van wat we willen weten staat in de matches property.

Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object -ExpandProperty Matches -First 1
Opsomming van de eigenschap Matches en beschikbare gegevens.
Opsomming van de eigenschap Matches en beschikbare gegevens.

Hier kunt u zien hoe, ook al hebben we een eenvoudige expressie gebruikt, dit nog steeds een RegEx-expressie is en de daaropvolgende details beschikbaar.

Wat als we naar verschillende waarden zoeken met behulp van door komma’s gescheiden patronen? Dit is handig omdat dit in feite drie verschillende patronen definieert en niet één complexe RegEx-waarde.

Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry"
Het teruggeven van meerdere overeenkomsten van een Select-String-zoekopdracht.
Meerdere resultaten van een zoekopdracht op basis van een Select-String.

U kunt zien hoe dit het geval is, als we alleen de filename, en pattern, en line uit onze zoekopdracht selecteren.

Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry" | Select-Object FileName, Pattern, Line

Filtering van de resultaten van een meervoudige Select-String-match.
Filtering van de resultaten van een meervoudige Select-String-match.

Meer complexe RegEx-matching

Nu we enkele van de eenvoudigere matching-methoden hebben gedemonstreerd, hoe zou het zijn om RegEx meer te gebruiken om daadwerkelijk naar bruikbaardere patronen te zoeken? De drie voorbeelden hier zijn het zoeken naar e-mailadressen, IP-adressen en sofinummers (SSN’s). De hier gebruikte patronen zijn niet de enige manier om een RegEx-zoekopdracht op te zetten, en er zijn wellicht eenvoudiger manieren. PowerShell Grep (Select-String) is een behoorlijk geavanceerd cmdlet.

Laten we eens kijken of er emails in onze bestanden staan. Met behulp van een ietwat complexe RegEx-match, zoals hieronder wordt getoond, wordt het vinden van die matches gedemonstreerd.

Select-String -Path "Users\*.csv" -Pattern '\\b+\.{2,4}\b' | Select-Object -First 10
Demonstreer het gebruik van RegEx om gegevens te matchen.
Demonstratie van het gebruik van RegEx om gegevens te matchen.

Het zou natuurlijk zorgwekkender zijn als er SSN’s in een bestand zijn opgenomen. Een heel eenvoudige match hiervoor zou het volgende zijn.

Select-String -Path "Users\*.csv" -Pattern '\d\d\d-\d\d-\d\d\d\d' | Select-Object -First 10
Demonstratie van een eenvoudige SSN RegEx-zoekopdracht.
Demonstratie van een eenvoudige SSN RegEx-zoekopdracht.

En wat als we een aantal IP-adressen in ons bestand willen opzoeken? Door een andere RegEx-expressie te gebruiken om naar dat patroon te zoeken, kunnen we snel werken.

Select-String -Path "Users\*.csv" -Pattern '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' | Select-Object -First 10
Demonstreer een eenvoudige RegEx-zoekopdracht voor IP-adressen.
Demonstratie van een eenvoudige IP-adres RegEx-zoekopdracht.

Een voorbehoud bij deze RegEx. Technisch gezien komt deze overeen met waarden tot 999.999.999.999, wat een ongeldig IP is. Je kunt nauwkeuriger RegEx expressies maken die langer worden, maar het is een afweging, afhankelijk van wat je wilt doen.

Zoeken met Context

Context is erg nuttig bij troubleshooting, het helpt om uit te leggen wat er gebeurt voordat een gebeurtenis optreedt en daarna. Laten we bijvoorbeeld eens zoeken in een Apache-logboek en deze suspendedpage.cgi tekst vinden.

Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -First 1
Zoeken naar een regel in een Apache-logboek.
Zoeken naar een regel in een Apache-log.

De > eenvoudig geeft de gematchte regel aan, en er is een regel vóór de overeenkomst en na de overeenkomst. In dit voorbeeld zou dit ons kunnen vertellen dat de Google bot op zoek was naar robots.txt en in plaats daarvan helaas een suspendedpage.cgi resultaat kreeg. Vervolgens probeerde hij de homepage en kreeg misschien dezelfde foutmelding.

Wat zit er dan precies in de context eigenschap zoals die door het MatchInfo object wordt uitgezonden? Als we die eigenschap uitbreiden, kunt u zien dat er PreContent en PostContent zijn. Dit betekent dat u dit verderop kunt manipuleren indien nodig.

Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -ExpandProperty Context -First 1 | Format-List
Demonstreer de Context-eigenschap.
Demonstreer de Context-eigenschap.

Andere voorbeelden van het doorzoeken van logbestanden vindt u in artikelen zoals Making Sense of the Microsoft DNS Debug Log, waarin wordt gedemonstreerd hoe u met Select-String een DNS-debuglog kunt doorzoeken. De PowerShell grep is sterk in die post.

Conclusie

Grep is een ongelooflijk handige tool in de Linux wereld, en Select-String biedt veel van dezelfde functionaliteit in de PowerShell wereld. Door de objectgeoriënteerde aard van PowerShell toe te voegen, worden het nut en de bruikbaarheid van het cmdlet alleen maar groter.

Voor veel systeembeheerders is het snel en efficiënt kunnen doorzoeken van logbestanden van verschillende typen, samen met het begrijpen van de context, een ongelooflijk belangrijke en noodzakelijke vaardigheid. PowerShell Select-String maakt dit gemakkelijk om te doen en bespaart talloze uren van troubleshooting!

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *