GNU/Linux >> Linux Esercitazione >  >> Linux

Iniziare con le espressioni regolari:un esempio

In Introduzione alle espressioni regolari , ho spiegato cosa sono e perché sono utili. Ora, abbiamo bisogno di un esempio del mondo reale da utilizzare come strumento di apprendimento. Eccone uno che ho incontrato diversi anni fa.

Questo esempio mette in evidenza la potenza e la flessibilità della riga di comando di Linux, in particolare le espressioni regolari, per la loro capacità di automatizzare le attività comuni. Ho amministrato diversi listserv durante la mia carriera e lo faccio ancora. Le persone mi inviano indirizzi e-mail da aggiungere a quegli elenchi. In più di un caso, ho ricevuto un elenco di nomi e indirizzi email in formato Microsoft Word da aggiungere a uno degli elenchi.

L'elenco dei problemi

L'elenco in sé non era molto lungo, ma era incoerente nella sua formattazione. Una versione abbreviata di tale elenco, con modifiche al nome e al dominio, è mostrata qui:

Team 1	Apr 3 
Leader  Virginia Jones  [email protected]	
Frank Brown  [email protected]	
Cindy Williams  [email protected]	
Marge smith   [email protected] 
 [Fred Mack]   [email protected]	

Team 2	March 14
leader  Alice Wonder  [email protected]	
John broth  [email protected]	
Ray Clarkson  [email protected]	
Kim West    [email protected]	
[JoAnne Blank]  [email protected]	

Team 3	Apr 1 
Leader  Steve Jones  [email protected]	
Bullwinkle Moose [email protected]	
Rocket Squirrel [email protected]	
Julie Lisbon  [email protected]	
[Mary Lastware) [email protected]

L'elenco originale aveva righe extra, caratteri come parentesi e parentesi che devono essere eliminati, spazi bianchi come spazi e tabulazioni e alcune righe vuote. Il formato richiesto per aggiungere queste email all'elenco è <first> <last> <[email protected]> . Il nostro compito è trasformare questa lista in un formato utilizzabile dal software di mailing list.

Era ovvio che dovevo manipolare i dati per trasformarli in un formato accettabile per l'inserimento nell'elenco. È possibile utilizzare un editor di testo o un elaboratore di testi come LibreOffice Writer per apportare le modifiche necessarie a questo piccolo file. Tuttavia, le persone mi inviano file come questo abbastanza spesso, quindi diventa un lavoro ingrato usare un elaboratore di testi per apportare queste modifiche. Nonostante Writer abbia una buona funzione di ricerca e sostituzione, ogni carattere o stringa deve essere sostituito singolarmente e non c'è modo di salvare le ricerche precedenti.

Writer ha una potente funzione macro, ma non ho familiarità con nessuno dei suoi due linguaggi:LibreOffice Basic o Python. Conosco la programmazione della shell Bash.

Ho fatto ciò che viene naturale per un amministratore di sistema:ho automatizzato l'attività. La prima cosa che ho fatto è stata copiare i dati dell'indirizzo in un file di testo in modo da poterci lavorare utilizzando gli strumenti della riga di comando. Dopo alcuni minuti di lavoro, ho sviluppato il programma da riga di comando Bash mostrato nell'articolo precedente:

$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/\]//g" -e "s/)//g" | awk '{print $1" "$2" <"$3">"}' > addresses.txt

Questo codice ha prodotto l'output desiderato come file addresses.txt . Ho usato il mio approccio normale per scrivere programmi da riga di comando come questo costruendo la pipeline un comando alla volta.

Suddividiamo questa pipeline nelle sue parti componenti per vedere come funziona e si adatta insieme. Tutti gli esperimenti di questa serie devono essere eseguiti come utente non privilegiato. L'ho fatto anche su una macchina virtuale che ho creato per il test:studentvm1 .

Il file di esempio

Innanzitutto, dobbiamo creare il file di esempio. Crea una directory denominata testing sul tuo computer locale, quindi copia il testo seguente in un nuovo file di testo denominato Experiment_6-1.txt , che contiene le tre voci di squadra mostrate sopra.

Team 1  Apr 3 
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  

Team 2  March 14
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]

Team 3  Apr 1 
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]

Rimuovere le righe non necessarie con grep

Le prime cose che vedo che si possono fare sono un paio di cose facili. Poiché i nomi e le date delle squadre sono sulle righe da sole, possiamo utilizzare quanto segue per rimuovere quelle righe che contengono la parola "Squadra:"

[student@studentvm1 testing]$  cat Experiment_6-1.txt | grep -v Team

Non riprodurrò i risultati di ogni fase della creazione di questo programma Bash, ma dovresti essere in grado di vedere le modifiche nel flusso di dati mentre viene visualizzato su STDOUT, la sessione del terminale. Non lo salveremo in un file fino alla fine.

In questo primo passaggio per trasformare il flusso di dati in uno utilizzabile, utilizziamo il grep comando con un semplice schema letterale, Team . I letterali sono il tipo più elementare di pattern che possiamo usare come espressione regolare, perché c'è solo una singola corrispondenza possibile nel flusso di dati che viene cercato, e questa è la stringa Team .

Dobbiamo scartare le righe vuote, così possiamo usare un altro grep dichiarazione per eliminarli. Trovo che racchiuda l'espressione regolare per il secondo grep il comando tra virgolette assicura che venga interpretato correttamente:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]
[Mary Lastware) [email protected]
[student@studentvm1 testing]$

L'espressione "^\s*$" illustra le ancore e utilizza la barra rovesciata (\) come carattere di escape per cambiare il significato di una "s" letterale (in questo caso) in un metacarattere che indica qualsiasi spazio bianco come spazi, tabulazioni o altri caratteri che non sono stampabili. Non possiamo vedere questi caratteri nel file, ma ne contiene alcuni.

L'asterisco, alias splat (*), specifica che dobbiamo trovare una corrispondenza con zero o più caratteri degli spazi bianchi. Questa aggiunta corrisponderebbe a più tabulazioni, più spazi o qualsiasi combinazione di quelli in una riga altrimenti vuota.

Visualizzare spazio bianco aggiuntivo con Vim

Successivamente, ho configurato il mio editor Vim per visualizzare gli spazi bianchi utilizzando caratteri visibili. Fallo aggiungendo la seguente riga al tuo ~.vimrc o nel file globale /etc/vimrc file di configurazione:

set listchars=eol:$,nbsp:_,tab:<->,trail:~,extends:>,space:+

Quindi, avvia o riavvia Vim.

Ho trovato molte informazioni negative, incomplete e contraddittorie su Internet nelle mie ricerche su come farlo. L'aiuto integrato di Vim ha le migliori informazioni e la linea di dati che ho creato da quella sopra è quella che funziona per me.

Nota: Nell'esempio seguente, gli spazi regolari sono mostrati come +; le schede vengono visualizzate come < , <> o <–> e riempi la lunghezza dello spazio coperto dalla linguetta. Il carattere di fine riga (EOL) viene visualizzato come $ .

Il risultato, prima di qualsiasi operazione sul file, viene mostrato qui:

Team+1<>Apr+3~$
[email protected]<-->$
[email protected]<---->$
[email protected]<--->$
[email protected]~$
+[Fred+Mack][email protected]<>$
$
Team+2<>March+14$
[email protected]<----->$
[email protected]<>$
[email protected]<-->$
[email protected]>$
[JoAnne+Blank][email protected]<---->$
$
Team+3<>Apr+1~$
[email protected]<-->$
[email protected]<--->$
[email protected]<>$
[email protected]<------>$
[Mary+Lastware)[email protected]$

Rimozione dei caratteri non necessari con sed

Puoi vedere che ci sono molti spazi bianchi che devono essere rimossi dal nostro file. Abbiamo anche bisogno di sbarazzarci della parola "leader", che appare due volte e una volta in maiuscolo. Prima sbarazziamoci del "leader". Questa volta useremo sed (editor di flusso) per eseguire questa attività sostituendo una nuova stringa, o una stringa nulla nel nostro caso, per il modello a cui corrisponde.

Aggiunta di sed -e "s/[Ll]eader//" alla pipeline fa questo:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//"

In questo sed comando, -e significa che l'espressione racchiusa tra virgolette è uno script che produce il risultato desiderato. Nell'espressione, le s significa che questa è una sostituzione. La forma base di una sostituzione è s/<regex>/<replacement string>/ , quindi /[Ll]eader/ è la nostra stringa di ricerca.

L'insieme [Ll] corrisponde a L o l , quindi [Ll]eader corrisponde a leader o Leader . In questo caso, la stringa di sostituzione è nulla perché sembra una doppia barra senza caratteri o spazi vuoti tra le due barre (// ).

Eliminiamo anche alcuni dei caratteri estranei come []() che non servirà:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g"

Abbiamo aggiunto quattro nuove espressioni a sed dichiarazione. Ognuno rimuove un singolo carattere. La prima di queste espressioni aggiuntive è leggermente diversa, perché la parentesi quadra sinistra ([ ) può segnare l'inizio di un set. Dobbiamo sfuggire alla parentesi per assicurarci che sed lo interpreta correttamente come un carattere regolare e non speciale.

Riordinare con awk

Potremmo usare sed per rimuovere gli spazi iniziali da alcune righe, ma il awk comando può farlo, riordinare i campi se necessario e aggiungere il <> caratteri intorno all'indirizzo email:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'

Il awk utility è in realtà un potente linguaggio di programmazione in grado di accettare flussi di dati sul proprio STDIN. Questo fatto lo rende estremamente utile nei programmi e negli script da riga di comando.

Il awk l'utilità funziona sui campi di dati e il separatore di campo predefinito è spazi, qualsiasi quantità di spazio bianco. Il flusso di dati che abbiamo creato finora ha tre campi separati da spazi bianchi (<first> , <last> e <email> ):

awk '{print $1" "$2" <"$3">"}'

Questo piccolo programma prende ciascuno dei tre campi ($1 , $2 e $3 ) e li estrae senza spazi vuoti iniziali o finali. Quindi li stampa in sequenza, aggiungendo un singolo spazio tra ciascuno e il <> caratteri necessari per racchiudere l'indirizzo email.

Conclusione

L'ultimo passaggio qui sarebbe reindirizzare il flusso di dati di output su un file, ma è banale, quindi lascio a te eseguire quel passaggio. Non è davvero necessario che tu lo faccia.

Ho salvato il programma Bash in un file eseguibile e ora posso eseguire questo programma ogni volta che ricevo un nuovo elenco. Alcuni di questi elenchi sono piuttosto brevi, come quello in questo esempio. Altri sono stati piuttosto lunghi, a volte contengono fino a diverse centinaia di indirizzi e molte righe di "roba" che non contengono indirizzi da aggiungere all'elenco.

Nota: Questo articolo è una versione leggermente modificata del capitolo 6 dal volume 2 del mio libro Linux, Using and Administering Linux:Zero to SysAdmin, in uscita da Apress alla fine del 2019.


Linux
  1. Iniziare con Zsh

  2. Iniziare con ls

  3. Iniziare con Samba per l'interoperabilità

  4. Iniziare con PostgreSQL su Linux

  5. Introduzione a SSH in Linux

Guida introduttiva a GitHub

Iniziare con Nix Package Manager

Iniziare con systemctl

Iniziare con cPanel

Iniziare con SiteApps

Guida introduttiva al comando Tar