Utilizzo di Grep e Espressioni Regolari per la Ricerca di Pattern di Testo in Linux

Introduzione

Il comando grep è uno dei comandi più utili in un ambiente di terminale Linux. Il nome grep sta per “global regular expression print”. Ciò significa che puoi utilizzare grep per verificare se l’input che riceve corrisponde a un determinato pattern. Questo programma apparentemente banale è estremamente potente; la sua capacità di ordinare l’input in base a regole complesse lo rende un collegamento popolare in molte catene di comandi.

In questo tutorial, esplorerai le opzioni del comando grep e poi ti immergerai nell’uso delle espressioni regolari per effettuare ricerche più avanzate.

Prerequisiti

Per seguire questa guida, avrai bisogno di accesso a un computer che esegua un sistema operativo basato su Linux. Questo può essere un server virtuale privato a cui ti sei connesso con SSH o il tuo computer locale. Nota che questo tutorial è stato validato utilizzando un server Linux con Ubuntu 20.04, ma gli esempi forniti dovrebbero funzionare su un computer con qualsiasi versione di qualsiasi distribuzione Linux.

Se hai intenzione di utilizzare un server remoto per seguire questa guida, ti incoraggiamo a completare prima la nostra guida Configurazione Iniziale del Server. Farlo ti permetterà di configurare un ambiente server sicuro, incluso un utente non root con privilegi sudo e un firewall configurato con UFW, che potrai utilizzare per sviluppare le tue competenze su Linux.

Utilizzo Base

In questo tutorial, utilizzerai grep per cercare la GNU General Public License versione 3 per varie parole e frasi.

Se sei su un sistema Ubuntu, puoi trovare il file nella cartella /usr/share/common-licenses. Copialo nella tua directory home:

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

Se sei su un altro sistema, utilizza il comando curl per scaricare una copia:

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

Userai anche il file della licenza BSD in questo tutorial. Su Linux, puoi copiarlo nella tua directory home con il seguente comando:

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

Se sei su un altro sistema, crea il file con il seguente comando:

  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

Ora che hai i file, puoi iniziare a lavorare con grep.

Nella forma più basilare, utilizzi grep per corrispondere a modelli letterali all’interno di un file di testo. Ciò significa che se passi a grep una parola da cercare, stamperà ogni riga nel file che contiene quella parola.

Eseguire il seguente comando per utilizzare grep per cercare ogni riga che contiene la parola GNU:

  1. grep "GNU" GPL-3

Il primo argomento, GNU, è il modello che stai cercando, mentre il secondo argomento, GPL-3, è il file di input che desideri cercare.

Il risultato sarà ogni riga contenente il testo del modello:

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

In alcuni sistemi, il modello che hai cercato verrà evidenziato nell’output.

Opzioni Comuni

Per impostazione predefinita, grep cercherà il modello specificato esattamente all’interno del file di input e restituirà le righe che trova. Tuttavia, puoi rendere questo comportamento più utile aggiungendo alcuni flag opzionali a grep.

Se desideri che grep ignori il “caso” del parametro di ricerca e cerchi variazioni sia in maiuscolo che in minuscolo, puoi specificare l’opzione -i o --ignore-case.

Cerca ogni istanza della parola license (con casi misti, maiuscoli o minuscoli) nello stesso file di prima con il seguente comando:

  1. grep -i "license" GPL-3

I risultati contengono: LICENSE, license e 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 ... ...

Se ci fosse stata un’istanza con LiCeNsE, quella sarebbe stata restituita anche.

Se vuoi trovare tutte le righe che non contengono un modello specificato, puoi utilizzare l’opzione -v o --invert-match.

Cerca ogni riga che non contiene la parola the nella licenza BSD con il seguente comando:

  1. grep -v "the" BSD

Riceverai questo 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 ... ...

Poiché non hai specificato l’opzione “ignora maiuscole/minuscole”, gli ultimi due elementi sono stati restituiti come non contenenti la parola the.

È spesso utile conoscere il numero di riga in cui si verificano le corrispondenze. Puoi farlo utilizzando l’opzione -n o --line-number. Riesegui l’esempio precedente con questo flag aggiunto:

  1. grep -vn "the" BSD

Questo restituirà il seguente testo:

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

Ora puoi fare riferimento al numero di riga se vuoi apportare modifiche a ogni riga che non contiene the. Questo è particolarmente utile quando si lavora con il codice sorgente.

Espressioni Regolari

Nell’introduzione, hai appreso che grep sta per “stampa espressione regolare globale”. Un’espressione regolare è una stringa di testo che descrive un particolare modello di ricerca.

Applicazioni diverse e linguaggi di programmazione implementano espressioni regolari leggermente in modo diverso. In questo tutorial esplorerai solo una piccola parte del modo in cui grep descrive i suoi modelli.

Corrispondenze Letterali

Negli esempi precedenti in questo tutorial, quando hai cercato le parole GNU e the, in realtà stavano cercando espressioni regolari di base che corrispondessero esattamente alla stringa di caratteri GNU e the. I modelli che specificano esattamente i caratteri da abbinare vengono chiamati “letterali” perché corrispondono letteralmente al modello, carattere per carattere.

È utile pensare a questi come alla corrispondenza di una stringa di caratteri piuttosto che alla corrispondenza di una parola. Questo diventerà una distinzione più importante man mano che imparerai modelli più complessi.

Tutti i caratteri alfabetici e numerici (nonché alcuni altri caratteri) sono abbinati letteralmente a meno che non siano modificati da altri meccanismi di espressione.

Corrispondenze Ancoraggio

Gli ancoraggi sono caratteri speciali che specificano dove nella riga deve verificarsi una corrispondenza per essere valida.

Ad esempio, utilizzando gli ancoraggi, puoi specificare che desideri solo le righe che corrispondono a GNU all’inizio della riga. Per fare ciò, potresti utilizzare l’ancoraggio ^ prima della stringa letterale.

Esegui il seguente comando per cercare nel file GPL-3 e trovare le righe in cui GNU compare all’inizio di una riga:

  1. grep "^GNU" GPL-3

Questo comando restituirà le seguenti due righe:

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

Allo stesso modo, usa l’ancora $ alla fine di un modello per indicare che la corrispondenza sarà valida solo se si verifica alla fine di una riga.

Questo comando corrisponderà a ogni riga che termina con la parola and nel file GPL-3:

  1. grep "and$" GPL-3

Riceverai questo output:

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

Corrispondenza con Qualsiasi Carattere

Il carattere punto (.) è utilizzato nelle espressioni regolari per indicare che può esistere un qualsiasi singolo carattere nella posizione specificata.

Ad esempio, per corrispondere a qualsiasi cosa nel file GPL-3 che abbia due caratteri e poi la stringa cept, useresti il seguente modello:

  1. grep "..cept" GPL-3

Questo comando restituisce il seguente output:

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

Questo output contiene istanze sia di accept che di except e variazioni delle due parole. Il modello avrebbe anche corrisposto a z2cept se fosse stato trovato anche quello.

Espressioni tra Parentesi Quadre

Posizionando un gruppo di caratteri tra parentesi quadre (\[ e \]), è possibile specificare che il carattere in quella posizione può essere uno qualsiasi dei caratteri presenti nel gruppo tra parentesi quadre.

Ad esempio, per trovare le righe che contengono troppo o due, è possibile specificare tali varianti in modo succinto utilizzando il seguente pattern:

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

L’output mostra che entrambe le varianti esistono nel file:

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

La notazione tra parentesi quadre offre alcune opzioni interessanti. È possibile far corrispondere il modello a qualsiasi cosa eccetto i caratteri all’interno di una parentesi quadra iniziando l’elenco dei caratteri all’interno delle parentesi quadre con il carattere ^.

Questo esempio è simile al modello .ode, ma non farà corrispondere il modello code:

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

Ecco l’output che riceverai:

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:

Nota che nella seconda riga restituita, è presente, infatti, la parola code. Questo non è un errore dell’espressione regolare o di grep. Piuttosto, questa riga è stata restituita perché in precedenza nella riga, è stato trovato il modello mode, presente nella parola modello. La riga è stata restituita perché c’era un’istanza che corrispondeva al modello.

Un’altra caratteristica utile delle parentesi quadre è che è possibile specificare un intervallo di caratteri invece di digitare singolarmente ogni carattere disponibile.

Ciò significa che se si desidera trovare ogni riga che inizia con una lettera maiuscola, è possibile utilizzare il seguente modello:

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

Ecco l’output restituito da questa espressione:

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

A causa di alcuni problemi di ordinamento ereditati, è spesso più accurato utilizzare le classi di caratteri POSIX invece degli intervalli di caratteri come hai appena usato.

Discutere ogni classe di caratteri POSIX sarebbe al di là dello scopo di questa guida, ma un esempio che otterrebbe la stessa procedura dell’esempio precedente utilizza la classe di caratteri \[:upper:\] all’interno di un selettore tra parentesi quadre:

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

Il risultato sarà lo stesso di prima.

Ripeti il Pattern Zero o Più Volte

Infine, uno dei meta-caratteri più comunemente utilizzati è l’asterisco, o *, che significa “ripeti il carattere o l’espressione precedente zero o più volte”.

Per trovare ogni riga nel file GPL-3 che contiene una parentesi di apertura e chiusura, con solo lettere e singoli spazi in mezzo, utilizza la seguente espressione:

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

Otterrai il seguente output:

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

Fino ad ora hai usato punti, asterischi e altri caratteri nelle tue espressioni, ma a volte è necessario cercare quei caratteri specificamente.

Caratteri di Meta-Escapamento

Ci sono momenti in cui avrai bisogno di cercare un punto letterale o una parentesi di apertura letterale, specialmente quando lavori con codice sorgente o file di configurazione. Poiché questi caratteri hanno un significato speciale nelle espressioni regolari, è necessario “escapare” questi caratteri per dire a grep che non desideri utilizzare il loro significato speciale in questo caso.

Si escapano i caratteri utilizzando il carattere backslash (\) davanti al carattere che avrebbe normalmente un significato speciale.

Per esempio, per trovare qualsiasi riga che inizia con una lettera maiuscola e finisce con un punto, usa la seguente espressione che escapa il punto finale in modo che rappresenti un punto letterale invece del solito significato di “qualsiasi carattere”:

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

Questo è l’output che vedrai:

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.

Ora vediamo altre opzioni per le espressioni regolari.

Espressioni regolari estese

Il comando grep supporta un linguaggio di espressioni regolari più esteso utilizzando il flag -E o chiamando il comando egrep invece di grep.

Queste opzioni aprono le capacità delle “espressioni regolari estese”. Le espressioni regolari estese includono tutti i meta-caratteri di base, insieme a ulteriori meta-caratteri per esprimere corrispondenze più complesse.

Raggruppamento

Una delle capacità più utili che le espressioni regolari estese aprono è la capacità di raggruppare le espressioni insieme per manipolarle o farvi riferimento come un’unica unità.

Per raggruppare le espressioni insieme, avvolgerle tra parentesi. Se si desidera utilizzare le parentesi senza utilizzare espressioni regolari estese, è possibile eludere con lo slash inverso per abilitare questa funzionalità. Ciò significa che le seguenti tre espressioni sono equivalenti dal punto di vista funzionale:

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

Alternanza

Similmente a come le espressioni tra parentesi quadre possono specificare diverse scelte possibili per le corrispondenze di caratteri singoli, l’alternanza consente di specificare corrispondenze alternative per stringhe o set di espressioni.

Per indicare l’alternanza, utilizzare il carattere pipe |. Questi sono spesso utilizzati all’interno di raggruppamenti parentetici per specificare che uno dei due o più possibili deve essere considerato una corrispondenza.

Il seguente troverà sia GPL che General Public License nel testo:

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

L’output appare così:

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

L’alternanza può selezionare tra più di due scelte aggiungendo scelte aggiuntive all’interno del gruppo di selezione separate da ulteriori caratteri pipe (|).

Quantificatori

Come il meta-carattere * che corrisponde al carattere precedente o al set di caratteri zero o più volte, ci sono altri meta-caratteri disponibili nelle espressioni regolari estese che specificano il numero di occorrenze.

Per corrispondere a un carattere zero o una volta, è possibile utilizzare il carattere ?. Questo rende opzionali i caratteri o i set di caratteri che sono venuti prima, in sostanza.

Il seguente corrisponde a copyright e right mettendo copy in un gruppo opzionale:

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

Riceverai questo 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 ...

Il carattere + corrisponde a un’espressione una o più volte. Questo è quasi come il meta-carattere *, ma con il carattere +, l’espressione deve corrispondere almeno una volta.

L’espressione seguente corrisponde alla stringa free più uno o più caratteri che non sono caratteri di spazio bianco:

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

Vedrai questo output:

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.

Specificare la Ripetizione della Corrispondenza

Per specificare il numero di volte che una corrispondenza viene ripetuta, utilizza i caratteri parentesi graffe ({ e }). Questi caratteri ti consentono di specificare un numero esatto, un intervallo, o un limite superiore o inferiore alla quantità di volte che un’espressione può corrispondere.

Utilizza l’espressione seguente per trovare tutte le righe nel file GPL-3 che contengono tripli vocali:

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

Ogni riga restituita ha una parola con tre vocali:

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

Per corrispondere a parole che hanno tra 16 e 20 caratteri, utilizza l’espressione seguente:

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

Ecco l’output di questo comando:

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

Vengono mostrate solo le righe contenenti parole di quella lunghezza.

Conclusione

grep è utile per trovare schemi all’interno dei file o all’interno della gerarchia del sistema di file, quindi vale la pena dedicare del tempo per familiarizzare con le sue opzioni e la sua sintassi.

Le espressioni regolari sono ancora più versatili e possono essere utilizzate con molti programmi popolari. Ad esempio, molti editor di testo implementano le espressioni regolari per cercare e sostituire il testo.

Inoltre, la maggior parte dei linguaggi di programmazione moderni utilizza le espressioni regolari per eseguire procedure su specifici pezzi di dati. Una volta comprese le espressioni regolari, sarai in grado di trasferire tale conoscenza a molte comuni attività informatiche, dalla ricerca avanzata nel tuo editor di testo alla convalida dell’input dell’utente.

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