Het Gebruik van Grep & Reguliere Expressies om te Zoeken naar Tekstpatronen in Linux

Introductie

De grep-opdracht is een van de meest nuttige opdrachten in een Linux-terminalomgeving. De naam grep staat voor “globale reguliere expressie afdrukken”. Dit betekent dat je grep kunt gebruiken om te controleren of de invoer die het ontvangt overeenkomt met een gespecificeerd patroon. Deze ogenschijnlijk triviale opdracht is uiterst krachtig; de mogelijkheid om invoer te sorteren op basis van complexe regels maakt het een populaire schakel in veel commandoketens.

In deze tutorial ga je de opties van de grep-opdracht verkennen, en vervolgens duik je in het gebruik van reguliere expressies om geavanceerder te zoeken.

Vereisten

Om deze handleiding te volgen, heb je toegang nodig tot een computer met een op Linux gebaseerd besturingssysteem. Dit kan een virtuele privéserver zijn waarop je bent verbonden met SSH of je lokale machine. Merk op dat deze tutorial is gevalideerd met behulp van een Linux-server met Ubuntu 20.04, maar de voorbeelden zouden moeten werken op een computer met elke versie van elke Linux-distributie.

Als je van plan bent om een externe server te gebruiken om deze handleiding te volgen, raden we je aan eerst onze Initial Server Setup handleiding te voltooien. Door dit te doen, stel je jezelf in staat om een veilige serveromgeving op te zetten, inclusief een niet-root gebruiker met sudo rechten en een firewall geconfigureerd met UFW, die je kunt gebruiken om je Linux-vaardigheden te ontwikkelen.

Basisgebruik

In deze handleiding ga je grep gebruiken om de GNU General Public License versie 3 te doorzoeken op verschillende woorden en zinnen.

Als je een Ubuntu-systeem gebruikt, kun je het bestand vinden in de map /usr/share/common-licenses. Kopieer het naar je thuismap:

  1. cp /usr/share/common-licenses/GPL-3 .

Als je een ander systeem gebruikt, gebruik dan het curl commando om een kopie te downloaden:

  1. curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt

Je zult ook het BSD-licentiebestand gebruiken in deze handleiding. Op Linux kun je dat naar je thuismap kopiëren met het volgende commando:

  1. cp /usr/share/common-licenses/BSD .

Als je een ander systeem gebruikt, maak dan het bestand aan met het volgende commando:

  1. cat << 'EOF' > BSD
  2. Copyright (c) The Regents of the University of California.
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions
  6. are met:
  7. 1. Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. 2. Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. 3. Neither the name of the University nor the names of its contributors
  13. may be used to endorse or promote products derived from this software
  14. without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  16. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  19. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. SUCH DAMAGE.
  26. EOF

Nu je de bestanden hebt, kun je aan de slag met grep.

In de meest basale vorm gebruik je grep om letterlijke patronen binnen een tekstbestand te matchen. Dit betekent dat als je grep een woord geeft om naar te zoeken, het elke regel in het bestand zal afdrukken die dat woord bevat.

Voer het volgende commando uit om grep te gebruiken om elke regel te zoeken die het woord GNU bevat:

  1. grep "GNU" GPL-3

De eerste argument, GNU, is het patroon waar je naar zoekt, terwijl het tweede argument, GPL-3, het invoerbestand is dat je wilt doorzoeken.

Het resulterende uitvoer zal elke regel bevatten die de patroontekst bevat:

Output
GNU GENERAL PUBLIC LICENSE The GNU General Public License is a free, copyleft license for the GNU General Public License is intended to guarantee your freedom to GNU General Public License for most of our software; it applies also to Developers that use the GNU GPL protect your rights with two steps: "This License" refers to version 3 of the GNU General Public License. 13. Use with the GNU Affero General Public License. under version 3 of the GNU Affero General Public License into a single ... ...

Op sommige systemen wordt het patroon dat je hebt gezocht, gemarkeerd in de uitvoer.

Veelvoorkomende opties

Standaard zal grep zoeken naar het exact gespecificeerde patroon binnen het invoerbestand en de gevonden regels retourneren. Je kunt dit gedrag echter nuttiger maken door enkele optionele vlaggen aan grep toe te voegen.

Als je wilt dat grep de “hoofdlettergevoeligheid” van je zoekparameter negeert en zoekt naar zowel hoofd- als kleine letters, kun je de optie -i of --ignore-case specificeren.

Zoek naar elk voorkomen van het woord license (met hoofdletters, kleine letters of gemengde gevallen) in hetzelfde bestand als voorheen met het volgende commando:

  1. grep -i "license" GPL-3

De resultaten bevatten: LICENSE, license en License:

Output
GNU GENERAL PUBLIC LICENSE of this license document, but changing it is not allowed. The GNU General Public License is a free, copyleft license for The licenses for most software and other practical works are designed the GNU General Public License is intended to guarantee your freedom to GNU General Public License for most of our software; it applies also to price. Our General Public Licenses are designed to make sure that you (1) assert copyright on the software, and (2) offer you this License "This License" refers to version 3 of the GNU General Public License. "The Program" refers to any copyrightable work licensed under this ... ...

Als er een geval was met LiCeNsE, zou dat ook zijn geretourneerd.

Als je alle regels wilt vinden die niet een specifiek patroon bevatten, kun je de optie -v of --invert-match gebruiken.

Zoek naar elke regel die het woord the niet bevat in de BSD-licentie met het volgende commando:

  1. grep -v "the" BSD

Je krijgt deze output:

Output
All rights reserved. Redistribution and use in source and binary forms, with or without are met: may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ... ...

Aangezien je de “ignore case” optie niet hebt gespecificeerd, werden de laatste twee items geretourneerd als zijnde zonder het woord the.

Het is vaak handig om te weten op welke regel de overeenkomsten voorkomen. Dit kun je doen door de optie -n of --line-number te gebruiken. Voer het vorige voorbeeld opnieuw uit met deze vlag toegevoegd:

  1. grep -vn "the" BSD

Dit zal de volgende tekst retourneren:

Output
2:All rights reserved. 3: 4:Redistribution and use in source and binary forms, with or without 6:are met: 13: may be used to endorse or promote products derived from this software 14: without specific prior written permission. 15: 16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ... ...

Nu kun je het regelnummer raadplegen als je wijzigingen wilt aanbrengen in elke regel die the niet bevat. Dit is vooral handig bij het werken met broncode.

Reguliere Expressies

In de inleiding heb je geleerd dat grep staat voor “global regular expression print”. Een “reguliere expressie” is een tekstreeks die een specifiek zoekpatroon beschrijft.

Verschillende toepassingen en programmeertalen implementeren reguliere expressies iets anders. In deze tutorial zul je slechts een kleine subset verkennen van de manier waarop grep zijn patronen beschrijft.

Letterlijke Overeenkomsten

In de vorige voorbeelden in deze handleiding, toen u zocht naar de woorden GNU en the, zocht u eigenlijk naar eenvoudige reguliere expressies die exact overeenkwamen met de string van karakters GNU en the. Patronen die precies de karakters specificeren die overeenkomen worden “letterlijk” genoemd omdat ze het patroon letterlijk, karakter voor karakter, overeenkomen.

Het is handig om deze te beschouwen als het overeenkomen met een reeks karakters in plaats van het overeenkomen met een woord. Dit zal een belangrijkere onderscheid worden naarmate u complexere patronen leert.

Alle alfabetische en numerieke karakters (evenals bepaalde andere karakters) worden letterlijk overeenkomend tenzij ze worden gewijzigd door andere expressiemechanismen.

Ankerovereenkomsten

Ankers zijn speciale karakters die aangeven waar in de regel een overeenkomst moet optreden om geldig te zijn.

Bijvoorbeeld, met behulp van ankers, kunt u specificeren dat u alleen wilt weten over de regels die overeenkomen met GNU helemaal aan het begin van de regel. Om dit te doen, kunt u het anker ^ gebruiken vóór de letterlijke string.

Voer de volgende opdracht uit om het bestand GPL-3 te doorzoeken en regels te vinden waar GNU voorkomt aan het begin van een regel:

  1. grep "^GNU" GPL-3

Deze opdracht retourneert de volgende twee regels:

Output
GNU General Public License for most of our software; it applies also to GNU General Public License, you may choose any version ever published

Vergelijkbaar gebruik je het anker $ aan het einde van een patroon om aan te geven dat de overeenkomst alleen geldig is als deze aan het einde van een regel voorkomt.

Deze opdracht komt overeen met elke regel die eindigt met het woord and in het bestand GPL-3:

  1. grep "and$" GPL-3

Je ontvangt deze uitvoer:

Output
that there is no warranty for this free software. For both users' and The precise terms and conditions for copying, distribution and License. Each licensee is addressed as "you". "Licensees" and receive it, in any medium, provided that you conspicuously and alternative is allowed only occasionally and noncommercially, and network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and provisionally, unless and until the copyright holder explicitly and receives a license from the original licensors, to run, modify and make, use, sell, offer for sale, import and otherwise run, modify and

Elk teken matchen

Het puntteken (.) wordt gebruikt in reguliere expressies om aan te geven dat elk willekeurig teken kan voorkomen op de opgegeven locatie.

Om bijvoorbeeld alles in het bestand GPL-3 te matchen dat uit twee tekens bestaat en vervolgens de tekenreeks cept, zou je het volgende patroon gebruiken:

  1. grep "..cept" GPL-3

Deze opdracht retourneert de volgende uitvoer:

Output
use, which is precisely where it is most unacceptable. Therefore, we infringement under applicable copyright law, except executing it on a tells the user that there is no warranty for the work (except to the License by making exceptions from one or more of its conditions. form of a separately written license, or stated as exceptions; You may not propagate or modify a covered work except as expressly 9. Acceptance Not Required for Having Copies. ... ...

Deze uitvoer bevat instanties van zowel accept als except en variaties van de twee woorden. Het patroon zou ook z2cept hebben overeenkomt als dat ook was gevonden.

Haakuitdrukkingen

Door een groep tekens tussen haakjes te plaatsen (\[ en \]), kunt u specificeren dat het teken op die positie elk teken kan zijn dat binnen de groep haakjes wordt gevonden.

Bijvoorbeeld, om de regels te vinden die too of two bevatten, zou u die variaties beknopt specificeren door het volgende patroon te gebruiken:

  1. grep "t[wo]o" GPL-3

De uitvoer laat zien dat beide variaties in het bestand voorkomen:

Output
your programs, too. freedoms that you received. You must make sure that they, too, receive Developers that use the GNU GPL protect your rights with two steps: a computer network, with no transfer of a copy, is not conveying. System Libraries, or general-purpose tools or generally available free Corresponding Source from a network server at no charge. ... ...

Met de haakjesnotatie heeft u enkele interessante opties. U kunt het patroon alles laten overeenkomen behalve de tekens binnen een haakje door de lijst met tekens binnen de haakjes te beginnen met een ^-teken.

Dit voorbeeld lijkt op het patroon .ode, maar zal niet overeenkomen met het patroon code:

  1. grep "[^c]ode" GPL-3

Hier is de uitvoer die u zult ontvangen:

Output
1. Source Code. model, to give anyone who possesses the object code either (1) a the only significant mode of use of the product. notice like this when it starts in an interactive mode:

Merk op dat in de tweede geretourneerde regel, het woord code inderdaad voorkomt. Dit is geen fout van de reguliere expressie of grep. Integendeel, deze regel werd geretourneerd omdat eerder in de regel het patroon mode, gevonden binnen het woord model, werd gevonden. De regel werd geretourneerd omdat er een instantie was die overeenkwam met het patroon.

Nog een handige functie van haakjes is dat u een reeks tekens kunt specificeren in plaats van elk beschikbaar teken afzonderlijk te typen.

Dit betekent dat als u elke regel wilt vinden die begint met een hoofdletter, u het volgende patroon kunt gebruiken:

  1. grep "^[A-Z]" GPL-3

Hier is de uitvoer die dit expressie retourneert:

Output
GNU General Public License for most of our software; it applies also to States should not allow patents to restrict development and use of License. Each licensee is addressed as "you". "Licensees" and Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an System Libraries, or general-purpose tools or generally available free Source. User Product is transferred to the recipient in perpetuity or for a ... ...

Vanwege enkele erfenis sorteerproblemen is het vaak nauwkeuriger om POSIX-karakterklassen te gebruiken in plaats van karakterreeksen zoals je zojuist hebt gebruikt.

Het bespreken van elke POSIX-karakterklasse zou buiten het bereik van deze handleiding vallen, maar een voorbeeld dat dezelfde procedure zou uitvoeren als het vorige voorbeeld, maakt gebruik van de karakterklasse \[:upper:\] binnen een haken selector:

  1. grep "^[[:upper:]]" GPL-3

Het uitvoer zal hetzelfde zijn als voorheen.

Herhaal Patroon Nul of Meer Keer

Tenslotte, een van de meest gebruikte meta-karakters is het asterisk, of *, wat betekent “herhaal het vorige karakter of de vorige expressie nul of meer keer”.

Om elke regel in het GPL-3 bestand te vinden die een openen en sluitende haakje bevat, met alleen letters en enkele spaties ertussen, gebruik de volgende expressie:

  1. grep "([A-Za-z ]*)" GPL-3

Je zult de volgende uitvoer krijgen:

Output
Copyright (C) 2007 Free Software Foundation, Inc. distribution (with or without modification), making available to the than the work as a whole, that (a) is included in the normal form of Component, and (b) serves only to enable use of the work with that (if any) on which the executable work runs, or a compiler used to (including a physical distribution medium), accompanied by the (including a physical distribution medium), accompanied by a place (gratis or for a charge), and offer equivalent access to the ... ...

Tot nu toe heb je punten, asterisken en andere karakters in je expressies gebruikt, maar soms moet je specifiek naar die karakters zoeken.

Ontsnappen aan Meta-Karakters

Er zijn momenten waarop je op zoek moet naar een letterlijke punt of een letterlijke openingshaakje, vooral bij het werken met broncode of configuratiebestanden. Omdat deze tekens een speciale betekenis hebben in reguliere expressies, moet je deze tekens “escapen” om grep te vertellen dat je hun speciale betekenis in dit geval niet wilt gebruiken.

Je escape tekens door het gebruik van het omgekeerde schuine streep-teken (\) vóór het teken dat normaal gesproken een speciale betekenis heeft.

Bijvoorbeeld, om elke regel te vinden die begint met een hoofdletter en eindigt met een punt, gebruik je de volgende expressie die het eindpunt escapet, zodat het een letterlijke punt voorstelt in plaats van de gebruikelijke betekenis van “elk teken”:

  1. grep "^[A-Z].*\.$" GPL-3

Dit is de output die je zult zien:

Output
Source. License by making exceptions from one or more of its conditions. License would be to refrain entirely from conveying the Program. ALL NECESSARY SERVICING, REPAIR OR CORRECTION. SUCH DAMAGES. Also add information on how to contact you by electronic and paper mail.

Laten we nu naar andere opties voor reguliere expressies kijken.

Uitgebreide reguliere expressies

De grep-opdracht ondersteunt een uitgebreidere reguliere expressietaal door gebruik te maken van de -E-vlag of door de egrep-opdracht in plaats van grep te gebruiken.

Deze opties openen de mogelijkheden van “uitgebreide reguliere expressies”. Uitgebreide reguliere expressies omvatten alle basismetatekens, samen met aanvullende metatekens om complexere overeenkomsten uit te drukken.

Groepering

Een van de meest nuttige mogelijkheden die uitgebreide reguliere expressies bieden, is het vermogen om expressies samen te groeperen om ze als één geheel te manipuleren of te verwijzen.

Om expressies samen te groeperen, omring ze met haakjes. Als u haakjes wilt gebruiken zonder uitgebreide reguliere expressies te gebruiken, kunt u ze escapen met de backslash om deze functionaliteit in te schakelen. Dit betekent dat de volgende drie expressies functioneel equivalent zijn:

  1. grep "\(grouping\)" file.txt
  2. grep -E "(grouping)" file.txt
  3. egrep "(grouping)" file.txt

Afwisseling

Vergelijkbaar met hoe haakse expressies verschillende mogelijke keuzes kunnen specificeren voor enkele karaktermatches, stelt afwisseling u in staat om alternatieve matches voor strings of expressiesets op te geven.

Om afwisseling aan te geven, gebruikt u het verticale streepje |. Deze worden vaak gebruikt binnen haakjesgroepering om aan te geven dat een van twee of meer mogelijkheden als een match moet worden beschouwd.

De volgende zal ofwel GPL of General Public License in de tekst vinden:

  1. grep -E "(GPL|General Public License)" GPL-3

Het resultaat ziet er als volgt uit:

Output
The GNU General Public License is a free, copyleft license for the GNU General Public License is intended to guarantee your freedom to GNU General Public License for most of our software; it applies also to price. Our General Public Licenses are designed to make sure that you Developers that use the GNU GPL protect your rights with two steps: For the developers' and authors' protection, the GPL clearly explains authors' sake, the GPL requires that modified versions be marked as have designed this version of the GPL to prohibit the practice for those ... ...

Afwisseling kan tussen meer dan twee keuzes selecteren door extra keuzes binnen de selectiegroep toe te voegen, gescheiden door extra verticale streep (|) tekens.

Kwantificeerders

Vergelijkbaar met het * metakarakter dat het vorige karakter of karakterreeks nul of meer keren overeenkomt, zijn er andere metakarakters beschikbaar in uitgebreide reguliere expressies die het aantal voorkomens specificeren.

Om een karakter nul of één keer overeen te laten komen, kunt u het ? karakter gebruiken. Hierdoor worden karakters of karakterreeksen die ervoor kwamen optioneel, in feite.

Het volgende komt overeen met copyright en right door copy in een optionele groep te plaatsen:

  1. grep -E "(copy)?right" GPL-3

U krijgt deze output:

Output
Copyright (C) 2007 Free Software Foundation, Inc. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License "Copyright" also means copyright-like laws that apply to other kinds of ...

Het + karakter komt overeen met een expressie één of meer keer. Dit is bijna hetzelfde als het * metakarakter, maar met het + karakter moet de expressie minstens één keer overeenkomen.

De volgende expressie komt overeen met de string free plus één of meer karakters die geen witruimtekarakters zijn:

  1. grep -E "free[^[:space:]]+" GPL-3

U zult deze output zien:

Output
The GNU General Public License is a free, copyleft license for to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to When we speak of free software, we are referring to freedom, not have the freedom to distribute copies of free software (and charge for you modify it: responsibilities to respect the freedom of others. freedomss that you received. You must make sure that they, too, receive protecting users' freedom to change the software. The systematic of the GPL, as needed to protect the freedom of users. patents cannot be used to render the program non-free.

Het specificeren van matchherhaling

Om het aantal keren dat een overeenkomst wordt herhaald te specificeren, gebruikt u de accoladekarakters ({ en }). Deze karakters stellen u in staat om een exact aantal, een bereik, of een bovengrens of ondergrens aan te geven voor het aantal keren dat een expressie kan overeenkomen.

Gebruik de volgende expressie om alle regels in het GPL-3-bestand te vinden die drie klinkers bevatten:

  1. grep -E "[AEIOUaeiou]{3}" GPL-3

Elke geretourneerde regel bevat een woord met drie klinkers:

Output
changed, so that their problems will not be attributed erroneously to authors of previous versions. receive it, in any medium, provided that you conspicuously and give under the previous paragraph, plus a right to possession of the covered work so as to satisfy simultaneously your obligations under this

Om woorden te vinden die tussen 16 en 20 tekens lang zijn, gebruikt u de volgende expressie:

  1. grep -E "[[:alpha:]]{16,20}" GPL-3

Hier is de uitvoer van deze opdracht:

Output
certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. c) Prohibiting misrepresentation of the origin of that material, or

Alleen regels die woorden van die lengte bevatten, worden weergegeven.

Conclusie

grep is handig om patronen te vinden binnen bestanden of binnen de bestandssysteemhiërarchie, dus het is de moeite waard om tijd te besteden aan het vertrouwd raken met de opties en syntax.

Reguliere expressies zijn nog veelzijdiger en kunnen worden gebruikt met veel populaire programma’s. Veel teksteditors implementeren bijvoorbeeld reguliere expressies voor het zoeken en vervangen van tekst.

Bovendien gebruiken de meeste moderne programmeertalen reguliere expressies om procedures uit te voeren op specifieke gegevensstukken. Zodra u reguliere expressies begrijpt, kunt u die kennis overdragen naar veelvoorkomende computergerelateerde taken, van het uitvoeren van geavanceerde zoekopdrachten in uw teksteditor tot het valideren van gebruikersinvoer.

Source:
https://www.digitalocean.com/community/tutorials/using-grep-regular-expressions-to-search-for-text-patterns-in-linux