Bash-regexps voor beginners met voorbeelden

  • Vovich Masterovich
  • 0
  • 1401
  • 428
>

Het gebruik van reguliere expressies in Bash geeft je voldoende kracht om bijna elke denkbare tekstreeks (of zelfs volledige documenten) te ontleden en om te zetten in bijna elke gewenste output. Als je regelmatig Bash gebruikt, of als je regelmatig met lijsten, tekstuele strings of documenten in Linux werkt, zul je merken dat veel taken vereenvoudigd kunnen worden door te leren hoe je reguliere expressies in Bash kunt gebruiken. Lees verder om de basisvaardigheden voor reguliere Bash-expressie te leren! Als je al bekend bent met reguliere reguliere expressies in Bash of een andere codeertaal, bekijk dan onze meer geavanceerde reguliere bash-expressies. Als dit niet het geval is, lees dan verder om de basisvaardigheden voor reguliere Bash-expressie te leren!

In deze tutorial leer je:

  • Hoe reguliere expressies te gebruiken op de opdrachtregel in Bash
  • Hoe reguliere expressies elke tekstreeks en / of document kunnen parseren en transformeren
  • Basisgebruiksvoorbeelden van reguliere expressies in Bash
Bash-regexps voor beginners met voorbeelden

Gebruikte softwarevereisten en -conventies

Softwarevereisten en Linux Command Line-conventies
Categorie Vereisten, conventies of gebruikte softwareversie
Systeem Linux-distributie-onafhankelijk
Software Bash-opdrachtregel, op Linux gebaseerd systeem
Andere Het hulpprogramma sed wordt gebruikt als een voorbeeldtool voor het gebruik van reguliere expressies
Conventies # - vereist dat gegeven linux-commando's worden uitgevoerd met root-privileges, hetzij direct als rootgebruiker, hetzij door gebruik van sudo opdracht
$ - vereist dat gegeven linux-commando's worden uitgevoerd als een gewone niet-geprivilegieerde gebruiker

Voorbeeld 1: onze eerste reguliere expressie

Er zijn verschillende algemene opdrachtregelhulpprogramma's zoals sed en grep die invoer van reguliere expressies accepteren. En u hoeft geen wijzigingen aan te brengen in de tool (gebruiken of instellen) om ook reguliere expressies te kunnen gebruiken; ze zijn standaard bewust van regex. Laten we eens kijken naar een voorbeeld zonder regex waarin we veranderen abc in xyz eerste:

$ echo 'abc' | sed 's / abc / xyz /' xyz 

Hier hebben we echo gebruikt om de string uit te voeren abc. Vervolgens geven we de uitvoer van deze echo door (met behulp van de pijp, d.w.z.. |, character) naar het sed-hulpprogramma. Sed is een stream-editor voor het filteren en transformeren van tekst. Ik moedig u aan om de gedetailleerde handleiding door te typen man sed op de opdrachtregel.

Eenmaal doorgegeven aan sed, transformeren we de string met behulp van een sed-specifieke (en regex-bewuste) syntaxis. Het commando dat we doorgeven aan sed (namelijk s / abc / xyz /) kan ook worden gelezen als vervang abc door wyz. De s staat voor substituut, en het scheidingsteken (/ in ons geval) geeft aan waar een sectie van de opdracht eindigt en / of een andere begint. Merk op dat we ook andere scheidingstekens in sed kunnen gebruiken, zoals |, zoals we in latere voorbeelden zullen zien.

Laten we dit commando nu veranderen in een voorbeeld van een reguliere expressie.

$ echo 'abc' | sed 's /./ xyz / g' xyzxyzxyz 


Wauw, wat is er hier gebeurd? :)

We hebben een paar kleine wijzigingen aangebracht, die de resulterende output aanzienlijk hebben beïnvloed. Ten eerste hebben we geruild abc in de sed-opdrachtregel naar .. Dit is geen gewone / letterlijke punt, maar eerder een punt met reguliere expressie. En, in reguliere expressie, betekent een punt elk karakter. De dingen zouden nu duidelijker moeten lijken, vooral als je de andere kleine wijziging opmerkt die we hebben aangebracht: g. De gemakkelijkste manier om over na te denken g is als globaal; een herhaaldelijk zoeken en vervangen.

Let hier ook op hoe s is ons eigenlijke sed-commando, gevolgd door de opties voor dat commando (de twee van-naar vervangende teksten), en de g is een kwalificatie boven het commando. Als u dit goed begrijpt, kunt u tegelijkertijd de sed-syntaxis leren.

Dus, in tegenstelling tot ons eerste voorbeeld van niet-reguliere expressies, en in natuurlijke taal, kan dit nieuwe commando worden gelezen als vervang een willekeurig teken door xyz, en herhaaldelijk ('globaal') doe dit totdat je het einde van de string bereikt. Met andere woorden, een wordt gewijzigd in xyz, b wordt gewijzigd in xyz enz., wat resulteert in de drievoudige uitvoer van xyz.

Allemaal aan boord? Super goed! Je hebt net geleerd hoe je reguliere expressies moet gebruiken. Laten we verder duiken.

Voorbeeld 2: een kleine waarschuwing

$ echo 'abc' | sed 's | \. | xyz | g' abc 

Oeps. Wat is er gebeurd? We hebben een paar kleine wijzigingen aangebracht en de uitvoer is aanzienlijk veranderd, net als in ons vorige voorbeeld. Reguliere expressies zijn erg krachtig, zoals je hier kunt zien, en zelfs een kleine wijziging kan een groot verschil maken in de uitvoer. Daarom is het meestal nodig om uw uitdrukkingen goed te testen. En hoewel dat hier niet het geval is, is het ook erg belangrijk om altijd te bedenken hoe de uitvoer van reguliere expressies kan worden beïnvloed door verschillende invoer. Vaak zal een licht gewijzigde of gewijzigde invoer een heel andere (en vaak foutieve) uitvoer opleveren.

We hebben twee kleine items gewijzigd; we hebben een \ voor de punt, en we hebben de scheidingstekens gewijzigd van / naar |. De laatste wijziging maakte absoluut geen verschil, zoals we uit deze output kunnen zien;

$ echo 'abc' | sed 's |. | xyz | g' xyzxyzxyz 


En we kunnen onze bevindingen tot nu toe dubbel controleren door deze opdracht te gebruiken:

$ echo 'abc' | sed 's /\./ xyz / g' abc 

Zoals verwacht, de | naar / verandering maakte geen verschil.

Dus terug naar ons dilemma - zullen we zeggen dat de kleine verandering van toevoegen \ is schuldig? Maar is het echt een fout?

Nee. Wat we hebben gedaan door deze eenvoudige wijziging aan te brengen, is de . punt in een letterlijke (\.) punt. Met andere woorden, dit is niet langer een echte reguliere expressie op het werk, maar een eenvoudige tekstuele tekenreeksvervanging die kan worden gelezen als vervang een letterlijke punt in xyz, en doe dit herhaaldelijk.

Laten we dit bewijzen;

$ echo 'ab… c' | sed 's /\./ xyz / g' abxyzxyzc 

Dit is zoals verwacht: de twee letterlijke punten zijn afzonderlijk gewijzigd (vanwege het repetitieve karakter van het g kwalificatie), naar xyz, algemene opbrengst abxyzxyzc.

Super! Laten we nu wat meer uitbreiden.

Voorbeeld 3: Kom maar op

Er gaat niets boven duiken met het hoofd eerst, toch? Misschien. Tot je dit ziet;

$ echo 'a… b… c' | sed 's | [\. b] \ + | d | g; s | [a-c] | d | g' ddd 

Ja, te complex, althans op het eerste gezicht. Laten we beginnen met een vereenvoudiging daarvan:

$ echo 'a… b… c' | sed 's | [\. b] \ + | d | g;' adc 

Ziet er nog een beetje lastig uit, maar je zult het snel begrijpen. Dus, neem de invoertekenreeks van een… b… c, we kunnen zien - op basis van ons vorige voorbeeld - dat we op zoek zijn naar een letterlijke punt (\.). In dit geval wordt het echter gevolgd door b en omgeven door [ en ]. Dit deel van de reguliere expressie ([\ .b]) kan worden gelezen als een letterlijke punt of het teken b (tot dusver niet herhaaldelijk; d.w.z. een enkel charter, een van beide, komt overeen met deze selector).

Vervolgens kwalificeren we dit wat verder door bij te voegen \+ hieraan selectievak. De \+ geeft aan dat we op zoek zijn naar ten minste één, en mogelijk meer, van deze vermelde tekens (letterlijke punt en b). Merk op dat de gezochte karakters in willekeurige volgorde naast elkaar moeten staan.

Bijvoorbeeld de tekst ... b ... bbbb ... zou nog steeds worden gematcht als een enkele gebeurtenis, terwijl … B… bbb… b.b… bb (let op de spatie) zou overeenkomen als afzonderlijk (herhalende) voorvallen, en beide (d.w.z. niet alleen de eerste) zouden worden vergeleken. En in dat geval zouden beide worden aangepakt vanwege de g globale / repetitieve kwalificatie.

Met andere woorden, in natuurlijke taal zouden we deze reguliere uitdrukking kunnen lezen als vervang een willekeurige opeenvolging van de tekens . en b met d en doe dit herhaaldelijk.

Kunt u zien wat er gebeurt? In de invoerstring hebben we ... b ... , die overeenkomt met de reguliere expressie omdat deze alleen bevat \. en b karakters. Het wordt dan vervangen d resulterend in adc.

Ons grotere voorbeeld ziet er nu ineens eenvoudiger uit. Laten we er terug naar springen:

$ echo 'a… b… c' | sed 's | [\. b] \ + | d | g; s | [a-c] | d | g' ddd 

Nadenken over hoe het eerste deel van het sed-commando transformeerde een… b… c in adc, we kunnen hier nu over nadenken adc als invoer voor het tweede commando in de sed; s | [a-c] | d | g. Merk op hoe beide sed-opdrachten worden gescheiden door ;.

Het enige dat gebeurt, is dat de uitvoer van de eerste wordt gebruikt als invoer voor het volgende commando. Dit werkt bijna altijd, hoewel er momenten zijn (bij gebruik van complexe tekst / documentaanpassing) dat het beter is om de uitvoer van het ene feitelijke sed-commando door te geven aan een ander sed-commando met behulp van een Bash-pipe (|).

Analyse van het tweede commando (s | [a-c] | d | g) zien we hoe we een andere hebben selectievak die letters van a tot c zal selecteren ([a-c])); de - geeft een reeks letters aan, die allemaal deel uitmaken van de syntaxis van de reguliere expressie.

De andere delen van dit commando spreken nu voor zich. In totaal kan dit tweede commando dus gelezen worden als vervang een letterlijk teken door bereik a-c (d.w.z. a, b of c) in d en doe dit herhaaldelijk. Het resultaat is dat de a, d en c (output van adc van ons eerste commando) worden weergegeven in ddd.

Dat zeer complexe commando ziet er nu niet meer zo eng uit, toch? Laten we afronden.

Voorbeeld 4: een afscheidsbericht

echo 'fijne dag verder' | sed's | $ | all |; s | y | y naar |; s | $ | u |; s | naar [la] \ + | naar | g; s | $ | alle | ' 


Kom je erachter? Tip; $ middelen einde van de lijn in reguliere expressies. De rest van deze complexe regex maakt gebruik van de kennis uit dit artikel. Wat is de output? Kijk of je het kunt achterhalen met een stuk papier, zonder de opdrachtregel te gebruiken. Als je dat deed - of niet :) - laat het ons weten in de reacties hieronder.

Gevolgtrekking

In deze tutorial hadden we een inleiding tot reguliere reguliere expressies, aangevuld met een paar (ironische) meer geavanceerde voorbeelden.

Wanneer u reguliere expressies leert en de code van anderen controleert, ziet u reguliere expressies die er ingewikkeld uitzien. Neem de tijd om ze uit te zoeken en speel met reguliere expressies op de opdrachtregel. Je zult snel een expert zijn, en hoewel analyse van complexe regexes meestal nodig is (de geest leent zich gewoon niet gemakkelijk om zo dichte informatie te lezen), wordt het gemakkelijker. Je zult ook merken dat een complex ogende regex bij verdere analyse er meestal vrij eenvoudig uitziet als je hem eenmaal begrijpt - net als in de bovenstaande voorbeelden.

Misschien wil je nu ook ons ​​artikel over reguliere expressies in Python lezen, aangezien veel van de daar verstrekte informatie ook van toepassing is op reguliere Bash-expressies, hoewel sommige opmaakvereisten enigszins verschillen. Het zal uw begrip van reguliere expressies vergroten, hoe u ze kunt gebruiken en hoe u ze in verschillende situaties en programmeertalen kunt toepassen. Als je eenmaal een regex-expert bent, vervaagt de kleine scheidslijn tussen tools en programmeertalen meestal en zul je de neiging hebben om specifieke syntaxisvereisten te onthouden voor elke taal of tool waarmee je werkt / waarmee je werkt.

!




Niemand heeft nog op dit artikel gereageerd.

Een verzameling nuttige informatie over het Linux-besturingssysteem en nieuwe technologieën
Nieuwe artikelen, praktische tips, gedetailleerde recensies en handleidingen. Voel je thuis in de wereld van het Linux-besturingssysteem