Shell Bash - 3 - Espressioni regolari

Posted by RedBlue on November 05, 2011 · 4 mins read

Terzo capitolo della guida alla shell Bash: oggi parliamo di espressioni regolari.

Prima di tutto, una definizione: si chiama espressione regolare una stringa che descrive un insieme di stringhe. Ovvero, un'espressione regolare è una sorta di schema (pattern) che descrive stringhe con caratteristiche simili.

Qual è l'utilità? Bè, semplicemente usando un'espressione regolare possiamo, con un'unica stringa, selezionarne n, in modo che un singolo script possa funzionare in n casi diversi.


Per raggiungere questo scopo, si usano dei metacaratteri, ovvero caratteri speciali che la shell processa ed espande, a seconda del loro significato. Questi metacaratteri sono i seguenti:

. $ ? * + - ^ \b \B \< \> { } [ ]

Questo il significato dei metacaratteri:

  • . ogni carattere;
  • $ stringa vuota a fine riga;
  • ? almeno una corrispondenza del carattere seguente;
  • * da zero a n corrispondenze del carattere che segue;
  • + da una a n corrispondenze del carattere che segue;
  • - indica un intervallo;
  • ^ stringa vuota ad inizio riga, oppure rappresenta i caratteri non compresi nella lista;
  • \b stringa vuota all'estremo di una parola
  • \B stringa vuota non all'estremo di una parola
  • \< stringa vuota all'inizio di una parola
  • \> stringa vuota alla fine di una parola
  • { } indicano una wildcard, le stringhe tra parentesi:
    • {N} esattamente N corrispondenze;
    • {N,} almeno N corrispondenze (ma anche di più);
    • {N,M} da N a M corrispondenze
  • [ ] altra wildcard, almeno un carattere tra quelli tra parentesi.

Vediamo alcuni esempi:

[a-z] - indica un singolo carattere all'interno dell'intervallo a-z;

[abcd] - indica un singolo carattere all'interno dell'insieme indicato;

^ciao - la stringa "ciao" all'inizio della riga;

\>giorno - la stringa "giorno" alla fine di una parola (es. buongiorno corrisponde a questo pattern);
è
ciao{N} - la stringa "ciao" appare esattamente N volte;

a.*b - indica una sola "a" prima di una sola "b";è

^a.*n$ - indica una riga che inizia con "a" e finisce con "b";

Attenzione perchè i metacaratteri ?, +, (, ), {, }, | devono essere preceduti dal caratteri di escape \ quando usiamo le espressioni regolari di base.

Esiste un'ulteriore wildcard: [[:CLASS:]], che indica un carattere nella classe CLASS, che a sua volta può assumere valori come alnum (carattere alfanumerico), alpha (carattere alfabetico), upper (maiuscola), lower (minuscola), digit (cifra), ad esempio:

\<[[:upper:]] - indica una parola che inizia con una lettera maiuscola.

Le espressioni regolari possono essere concatenate, ovvero una stringa corrisponde ad una concatenazione di espressioni regolari se è composta da due sottostringhe che corrispondono rispettivamente alle due espressioni regolari. Si può usare anche l'operatore | (pipe), ad esempio esp1|esp2 significa "esp1 oppure esp2".

Nella valutazione di un'espressione regolare, l'ordine di precedenza riguarda prima la ripetizione, poi la concatenazione e infine l'operatore |, a meno ovviamente di usare le parentesi tonde per modificare tale ordine.

Da dire infine che queste informazioni possono essere usate comunemente nella shell, non solo per uno script. Ad esempio, il comando grep serve a cercare una determinata stringa all'interno di un file. Bene, tramite questo comando ovviamente possono essere reperite moltissime informazioni (pensate di dover cercare le righe relative ad una certa periferica all'interno di un file di log estremamente lungo e complesso) e l'uso delle espressioni regolari può facilitare il compito. Un esempio:

grep '\(501:\)\{2\}' /etc/passwd

Cerca e ritorna tutte le righe che contengono due occorrenze della stringa "501" all'interno del file indicato.

Alla prossima..