103.7 Lezione 2
Certificazione: |
LPIC-1 |
---|---|
Versione: |
5.0 |
Argomento: |
103 Comandi GNU e Unix |
Obiettivo: |
103.7 Cercare file di testo utilizzando espressioni regolari |
Lezione: |
2 di 2 |
Introduzione
Lo streaming dei dati attraverso una catena di comandi in pipe consente l’applicazione di filtri composti basati su espressioni regolari. Le espressioni regolari sono una tecnica importante utilizzata non solo nell’amministrazione del sistema, ma anche nel data mining e nelle aree correlate. Due comandi sono particolarmente adatti per manipolare file e dati di testo usando espressioni regolari: grep
e sed
. grep
è un cercatore di pattern e sed
è un editor di flussi. Sono utili da soli, ma è quando lavorano insieme ad altri processi che diventano insostituibili.
Il "Cercatore" di Pattern: grep
Uno degli usi più comuni di grep
è quello di facilitare l’ispezione di file lunghi, utilizzando l’espressione regolare come filtro applicato a ciascuna riga. Può essere utilizzato per mostrare solo le righe che iniziano con un certo termine. grep
può essere usato per cercare in un file di configurazione i moduli del kernel, elencando solo le righe delle opzioni:
$ grep '^options' /etc/modprobe.d/alsa-base.conf options snd-pcsp index=-2 options snd-usb-audio index=-2 options bt87x index=-2 options cx88_alsa index=-2 options snd-atiixp-modem index=-2 options snd-intel8x0m index=-2 options snd-via82xx-modem index=-2
Il carattere pipe |
può essere impiegato per reindirizzare l’output di un comando direttamente all’input di grep
. L’esempio seguente utilizza un’espressione con parentesi quadre per selezionare le righe dall’output di fdisk -l
, che iniziano con Disk /dev/sda
o Disk /dev/sdb
:
# fdisk -l | grep '^Disk /dev/sd[ab]' Disk /dev/sda: 320.1 GB, 320072933376 bytes, 625142448 sectors Disk /dev/sdb: 7998 MB, 7998537728 bytes, 15622144 sectors
La semplice selezione di linee con corrispondenze potrebbe non essere appropriata per un compito particolare, richiedendo aggiustamenti al comportamento di grep
attraverso le sue opzioni. Per esempio, l’opzione -c
o --count
dice a grep
di mostrare quante righe hanno corrispondenze:
# fdisk -l | grep '^Disk /dev/sd[ab]' -c 2
L’opzione può essere inserita prima o dopo l’espressione regolare. Altre importanti opzioni di grep
sono:
-c
o--count
-
Invece di visualizzare i risultati della ricerca, visualizza solo il conteggio totale del numero di volte in cui si verifica una corrispondenza in un determinato file.
-i
o--ignore-case
-
Imposta la ricerca senza distinzione tra maiuscole e minuscole.
-f FILE
o--file=FILE
-
Indica un file contenente l’espressione regolare da utilizzare.
-n
o--line-number
-
Mostra il numero della riga.
-v
o--invert-match
-
Seleziona ogni riga, tranne quelle che contengono corrispondenze.
-H
o--with-filename
-
Stampa anche il nome del file contenente la riga.
-z
o--null-data
-
Invece di fare in modo che
grep
tratti i flussi di dati di input e output come linee separate (usando newline per impostazione predefinita), prendi l’input o l’output come una sequenza di righe. Quando si combina l’output del comandofind
usando la sua opzione-print0
con il comandogrep
, l’opzione-z
o--null-data
dovrebbe essere usata per elaborare lo stream nello stesso modo.
Sebbene sia attivata per impostazione predefinita quando vengono forniti più percorsi di file come input, l’opzione -H
non è attivata per singoli file. Ciò può essere critico in situazioni speciali, come quando grep
viene chiamato direttamente da find
, per esempio:
$ find /usr/share/doc -type f -exec grep -i '3d modeling' "{}" \; | cut -c -100 artistic aspects of 3D modeling. Thus this might be the application you are This major approach of 3D modeling has not been supported oce is a C++ 3D modeling library. It can be used to develop CAD/CAM softwares, for instance [FreeCad
In questo esempio, find
elenca tutti i file in /usr/share/doc
, quindi li passa ciascuno a grep
, che a sua volta esegue una ricerca senza distinzione tra maiuscole e minuscole per 3d modeling
all’interno del file. Il flusso da tagliare (cut
) serve solo per limitare la lunghezza di output a 100 colonne. Notare, tuttavia, che non c’è modo di sapere da quale file provengano le righe. Questo problema viene risolto aggiungendo -H
a grep
:
$ find /usr/share/doc -type f -exec grep -i -H '3d modeling' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support
Ora è possibile identificare i file in cui è stata trovata ogni corrispondenza. Per rendere l’elenco ancora più informativo, è possibile aggiungere righe iniziali e finali alle righe con corrispondenze:
$ find /usr/share/doc -type f -exec grep -i -H -1 '3d modeling' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p /usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support /usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.
L’opzione -1
dice a grep
di includere una riga prima e una riga dopo la riga trovata con una corrispondenza. Queste righe aggiuntive sono chiamate linee di contesto e sono identificate nell’output da un segno meno dopo il nome del file. Lo stesso risultato può essere ottenuto con -C 1
o --context=1
e possono essere indicate altre quantità di righe di contesto.
Ci sono due programmi complementari a grep: egrep
e fgrep
. Il programma egrep
è equivalente al comando grep -E
, che incorpora funzionalità extra oltre alle espressioni regolari di base. Per esempio, con egrep
è possibile utilizzare funzionalità di espressioni regolari estese, come la ramificazione:
$ find /usr/share/doc -type f -exec egrep -i -H -1 '3d (modeling|printing)' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p /usr/share/doc/openscad/RELEASE_NOTES.md-* Support for using 3D-Mouse / Joystick / Gamepad input dev /usr/share/doc/openscad/RELEASE_NOTES.md:* 3D Printing support: Purchase from a print service partne /usr/share/doc/openscad/RELEASE_NOTES.md-* New export file formats: SVG, 3MF, AMF /usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support /usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.
In questo esempio, 3D modeling
o 3D printing
corrisponderanno all’espressione, senza distinzione tra maiuscole e minuscole. Per visualizzare solo le parti di un flusso di testo che corrispondono all’espressione usata da egrep
, utilizzare l’opzione -o
.
Il programma fgrep
è equivalente a grep -F
, cioè non analizza le espressioni regolari: è utile nelle ricerche semplici in cui l’obiettivo è trovare una corrispondenza con un’espressione letterale. Pertanto, caratteri speciali come il simbolo del dollaro e il punto verranno presi alla lettera e non dal loro significato in un’espressione regolare.
L’Editor di Stream: sed
Lo scopo del programma sed
è quello di modificare i dati basati su testo in modo non interattivo. Questo significa che tutte le modifiche vengono effettuate tramite istruzioni predefinite, non digitando direttamente su un testo visualizzato a schermo. In termini "moderni", sed
può essere inteso come un template parser: dato un testo come input, colloca il contenuto personalizzato in posizioni predefinite o quando trova una corrispondenza per un’espressione regolare.
Sed, come suggerisce il nome, è adatto per il testo trasmesso tramite pipeline. La sua sintassi di base è sed -f SCRIPT
quando le istruzioni di modifica sono memorizzate nel file SCRIPT
o sed -e COMMANDS
per eseguire COMMANDS
direttamente dalla riga di comando. Se non sono presenti ne -f
ne -e
, sed
utilizza il primo parametro non di opzione come file di script. È anche possibile usare un file come input semplicemente dando il suo percorso come argomento a sed
.
Le istruzioni sed
sono composte da un singolo carattere, possibilmente preceduto da un indirizzo o seguite da una o più opzioni, e vengono applicate ad una riga alla volta. Gli indirizzi possono essere un numero di riga singola, un’espressione regolare o un intervallo di righe. Per esempio, la prima riga di un flusso di testo può essere eliminata con 1d
, dove 1
specifica la riga in cui verrà applicato il comando di eliminazione d
. Per chiarire l’uso di sed
, prendi l’output del comando factor `seq 12`
, che restituisce i fattori primi per i numeri da 1 a 12:
$ factor `seq 12` 1: 2: 2 3: 3 4: 2 2 5: 5 6: 2 3 7: 7 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
L’eliminazione della prima riga con sed
si ottiene con 1d
:
$ factor `seq 12` | sed 1d 2: 2 3: 3 4: 2 2 5: 5 6: 2 3 7: 7 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
È possibile specificare un intervallo di righe con una virgola di separazione:
$ factor `seq 12` | sed 1,7d 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
È possibile utilizzare più di un’istruzione nella stessa esecuzione, separate da punto e virgola. In questo caso, però, è importante racchiuderli tra virgolette in modo che il punto e virgola non venga interpretato dalla shell:
$ factor `seq 12` | sed "1,7d;11d" 8: 2 2 2 9: 3 3 10: 2 5 12: 2 2 3
In questo esempio, sono state eseguite due istruzioni di cancellazione, prima sulle righe da 1 a 7 e poi sulla riga 11. Un indirizzo può anche essere un’espressione regolare, quindi solo le righe con una corrispondenza saranno influenzate dall’istruzione:
$ factor `seq 12` | sed "1d;/:.*2.*/d" 3: 3 5: 5 7: 7 9: 3 3 11: 11
L’espressione regolare :.*2.*
corrisponde a qualsiasi occorrenza del numero 2 in qualsiasi punto dopo i due punti, causando la cancellazione delle righe corrispondenti ai numeri con 2 come fattore. Con sed
, qualsiasi cosa inserita tra gli slash (/
) è considerata un’espressione regolare e per impostazione predefinita sono supportate tutte le RE di base. Per esempio, sed -e "/^#/d" /etc/services
mostra il contenuto del file /etc/services
senza le righe che iniziano con #
(righe di commento).
L’istruzione di cancellazione d
è solo una delle tante istruzioni di modifica fornite da sed
. Invece di eliminare una riga, sed
può sostituirla con un dato testo:
$ factor `seq 12` | sed "1d;/:.*2.*/c REMOVED" REMOVED 3: 3 REMOVED 5: 5 REMOVED 7: 7 REMOVED 9: 3 3 REMOVED 11: 11 REMOVED
L’istruzione c REMOVED
sostituisce semplicemente una riga con il testo REMOVED
. Nel caso dell’esempio, ogni riga con una sottostringa che corrisponde all’espressione regolare :.*2.*
è influenzata dall’istruzione c REMOVED
. L’istruzione a TEXT
copia il testo indicato da TEXT
in una nuova riga dopo la riga con una corrispondenza. L’istruzione r FILE
fa lo stesso, ma copia il contenuto del file indicato da FILE
. L’istruzione w
fa l’opposto di r
, cioè la riga verrà aggiunta al file indicato.
Di gran lunga l’istruzione sed
più usata è s/FIND/REPLACE/
, che viene usata per sostituire una corrispondenza all’espressione regolare FIND
con il testo indicato da REPLACE
. Per esempio, l’istruzione s/hda/sda/
sostituisce una sottostringa che corrisponde al letterale RE hda
con sda
. Solo la prima corrispondenza trovata nella riga verrà sostituita, a meno che il flag g
non sia posto dopo l’istruzione, come in s/hda/sda/g
.
Un caso più realistico aiuterà a illustrare le caratteristiche di sed
. Supponiamo che una clinica medica desideri inviare messaggi di testo ai propri clienti, ricordando loro gli appuntamenti programmati per il giorno successivo. Uno scenario di implementazione tipico si basa su un servizio di messaggistica istantanea professionale, che fornisce un’API per accedere al sistema responsabile della consegna dei messaggi. Questi messaggi di solito provengono dallo stesso sistema che esegue l’applicazione controllando gli appuntamenti del cliente, messaggi attivati a un momento specifico della giornata o da qualche specifico evento. In questa ipotetica situazione l’applicazione potrebbe generare un file chiamato appointments.csv
contenente i dati tabulati con tutti gli appuntamenti per il giorno successivo, poi usato da sed
per visualizzare i messaggi di testo da un file modello chiamato template.txt
. I file CSV sono un modo standard per esportare i dati dalle query del database, quindi gli appuntamenti di esempio potrebbero essere forniti come segue:
$ cat appointments.csv "NAME","TIME","PHONE" "Carol","11am","55557777" "Dave","2pm","33334444"
La prima riga contiene le etichette per ogni colonna, che verranno utilizzate per abbinare i tag all’interno del file modello di esempio:
$ cat template.txt Hey <NAME>, don't forget your appointment tomorrow at <TIME>.
I segni minore di <
e maggiore di >
sono stati posti attorno alle etichette solo per aiutare a identificarli come tag. Il seguente script Bash analizza tutti gli appuntamenti accodati usando template.txt
come modello di messaggio:
#! /bin/bash TEMPLATE=`cat template.txt` TAGS=(`sed -ne '1s/^"//;1s/","/\n/g;1s/"$//p' appointments.csv`) mapfile -t -s 1 ROWS < appointments.csv for (( r = 0; r < ${#ROWS[*]}; r++ )) do MSG=$TEMPLATE VALS=(`sed -e 's/^"//;s/","/\n/g;s/"$//' <<<${ROWS[$r]}`) for (( c = 0; c < ${#TAGS[*]}; c++ )) do MSG=`sed -e "s/<${TAGS[$c]}>/${VALS[$c]}/g" <<<"$MSG"` done echo curl --data message=\"$MSG\" --data phone=\"${VALS[2]}\" https://mysmsprovider/api done
Uno script in produzione gestirà anche l’autenticazione, il controllo degli errori e la registrazione, ma l’esempio ha funzionalità di base con cui iniziare. Le prime istruzioni eseguite da sed
sono applicate solo alla prima riga: l’indirizzo 1
in 1s/^"//;1s/","/\n/g;1s/"$//p
— per rimuovere le virgolette iniziali e finali — 1s/^"//
e 1s/"$//
— e per sostituire i separatori di campo con un carattere di nuova riga: 1s /","/\n/g
. Solo la prima riga è necessaria per caricare i nomi delle colonne, quindi le righe non corrispondenti verranno soppresse dall’opzione -n
, richiedendo che il flag p
sia posto dopo l’ultimo comando sed
per stampare la riga corrispondente. I tag vengono quindi memorizzati nella variabile TAGS
come un array Bash. Un’altra variabile dell'array Bash viene creata dal comando mapfile
per memorizzare le righe contenenti gli appuntamenti nella variabile dell’array ROWS
.
Un ciclo for
viene utilizzato per elaborare ogni riga di appuntamento trovata in ROWS
. Quindi, virgolette e separatori nell’appuntamento — l’appuntamento è nella variabile ${ROWS[$r]}
usata come here string — vengono sostituiti da sed
, in modo simile ai comandi usati per caricare i tag. I valori separati per l’appuntamento vengono quindi memorizzati nella variabile di array VALS
, dove gli indici di array 0, 1 e 2 corrispondono ai valori di NAME
, TIME
e PHONE
.
Infine, un ciclo annidato for
percorre l’array TAGS
e sostituisce ogni tag trovato nel modello con il valore corrispondente in VALS
. La variabile MSG
contiene una copia del modello renderizzato, aggiornato dal comando di sostituzione s/<${TAGS[$ c]}>/${VALS[$c]}/g
ad ogni ciclo che passa attraverso TAGS
.
Ciò si traduce in un messaggio visualizzato come: "Ehi Carol, non dimenticare il tuo appuntamento domani alle 11:00."
Il messaggio visualizzato può quindi essere inviato come parametro tramite una richiesta HTTP con curl
, come messaggio di posta elettronica o un altro metodo simile
Combinare grep e sed
I comandi grep
e sed
possono essere usati insieme quando sono richieste procedure di text mining più complesse. In qualità di amministratore di sistema, potresti voler controllare tutti i tentativi di accesso a un server. Per esempio, il file /var/log/wtmp
registra tutti i login e logout, mentre il file /var/log/btmp
registra i tentativi di login falliti. Sono scritti in un formato binario, che può essere letto rispettivamente dai comandi last
e lastb
.
L’output di lastb
mostra non solo il nome utente utilizzato nel tentativo di accesso errato, ma anche il suo indirizzo IP:
# lastb -d -a -n 10 --time-format notime user ssh:notty (00:00) 81.161.63.251 nrostagn ssh:notty (00:00) vmd60532.contaboserver.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 46.6.11.56 pi ssh:notty (00:00) 46.6.11.56 nps ssh:notty (00:00) vmd60532.contaboserver.net narmadan ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net
L’opzione -d
traduce l’indirizzo IP nel nome host corrispondente. Il nome host può fornire indizi sull’ISP o sul servizio di hosting utilizzato per eseguire questi tentativi di accesso errati. L’opzione -a
inserisce il nome host nell’ultima colonna, il che facilita il filtraggio ancora da applicare. L’opzione --time-format notime
sopprime l’ora in cui si è verificato il tentativo di accesso. Il comando lastb
può richiedere del tempo per terminare se ci sono stati troppi tentativi di accesso errati, quindi l’output è stato limitato a dieci voci con l’opzione -n 10
.
Non tutti gli IP remoti hanno un nome host associato, quindi il DNS inverso non si applica a loro e possono essere ignorati. Sebbene sia possibile scrivere un’espressione regolare che corrisponda al formato previsto per un nome host alla fine della riga, è probabilmente più semplice scrivere un’espressione regolare da abbinare a una lettera dell’alfabeto o a una singola cifra alla fine del linea. L’esempio seguente mostra come il comando grep
prende l’elenco nel suo standard input e rimuove le righe senza nomi host:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | head -n 10 nvidia ssh:notty (00:00) vmd60532.contaboserver.net n_tonson ssh:notty (00:00) vmd60532.contaboserver.net nrostagn ssh:notty (00:00) vmd60532.contaboserver.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net nps ssh:notty (00:00) vmd60532.contaboserver.net narmadan ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net
L’opzione -v
del comando grep
mostra solo le righe che non corrispondono all’espressione regolare data. Un’espressione regolare che corrisponde a qualsiasi riga che termina con un numero (per esempio [0-9]$
) catturerà solo le voci senza un nome host. Pertanto, grep -v '[0-9]$'
mostrerà solo le righe che finiscono con un nome host.
L’output può essere ulteriormente filtrato, mantenendo solo il nome di dominio e rimuovendo le altre parti da ogni riga. Il comando sed
può farlo con un comando di sostituzione per modificare l’intera riga con un riferimento al nome di dominio in essa contenuto:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | head -n 10 vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net 132.red-88-20-39.staticip.rima-tde.net 132.red-88-20-39.staticip.rima-tde.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net
La parentesi con escape in .* \(.*\)$
indica a sed
di ricordare quella parte della riga, cioè la parte tra l’ultimo carattere di spazio e la fine della riga. Nell’esempio, questa parte viene referenziata con \ 1
e viene utilizzata la sostituzione dell’intera riga.
È chiaro che la maggior parte degli host remoti tenta di accedere più di una volta, quindi lo stesso nome di dominio si ripete. Per sopprimere le voci ripetute, prima devono essere ordinate (con il comando sort
) quindi passate al comando uniq
:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | sort | uniq | head -n 10 116-25-254-113-on-nets.com 132.red-88-20-39.staticip.rima-tde.net 145-40-33-205.power-speed.at tor.laquadrature.net tor.momx.site ua-83-226-233-154.bbcust.telenor.se vmd38161.contaboserver.net vmd60532.contaboserver.net vmi488063.contaboserver.net vmi515749.contaboserver.net
Questo mostra come sia possibile combinare diversi comandi per produrre il risultato desiderato. L’elenco dei nomi host può quindi essere utilizzato per scrivere regole di blocco del firewall o per adottare altre misure per rafforzare la sicurezza del server.
Esercizi Guidati
-
Il comando
last
mostra un elenco degli ultimi utenti che hanno effettuato un accesso sul sistema, inclusi i loro IP di origine. Come verrebbe usato il comandoegrep
per filtrare l’output dilast
, mostrando solo le occorrenze di un indirizzo IPv4, scartando qualsiasi informazione aggiuntiva nella riga corrispondente? -
Quale opzione dovrebbe essere data a
grep
per filtrare correttamente l’output generato dal comandofind
eseguito con l’opzione-print0
? -
Il comando
uptime -s
mostra l’ultima data in cui il sistema è stato acceso, come in2019-08-05 20:13:22
. Quale sarà il risultato del comandouptime -s | sed -e 's/(.*) (.*)/\1/'
? -
Quale opzione dovrebbe essere data a
grep
in modo che conti le linee corrispondenti invece di visualizzarle?
Esercizi Esplorativi
-
La struttura di base di un file HTML inizia con gli elementi
html
,head
ebody
, per esempio:<html> <head> <title>News Site</title> </head> <body> <h1>Headline</h1> <p>Information of interest.</p> </body> </html>
Descrivi come gli indirizzi potrebbero essere usati in
sed
per visualizzare solo l’elementobody
e il suo contenuto. -
Quale espressione di
sed
rimuoverà tutti i tag da un documento HTML, mantenendo solo il testo visualizzato? -
I file con estensione
.ovpn
sono molto popolari per configurare i client VPN poiché contengono non solo le impostazioni, ma anche il contenuto delle chiavi e dei certificati per il client. Queste chiavi e certificati sono originariamente in file separati, quindi devono essere copiati nel file.ovpn
. Dato il seguente estratto di un modello.ovpn
:client dev tun remote 192.168.1.155 1194 <ca> ca.crt </ca> <cert> client.crt </cert> <key> client.key </key> <tls-auth> ta.key </tls-auth>
Supponendo che i file
ca.crt
,client.crt
,client.key
eta.key
si trovino nella directory corrente, come verrebbe modificata la configurazione del modello dised
per sostituire ogni nome di file con il suo contenuto?
Sommario
Questa lezione copre i due comandi Linux più importanti relativi alle espressioni regolari: grep
e sed
. Script e comandi composti si basano su grep
e sed
per eseguire un’ampia gamma di operazioni di filtraggio e analisi del testo. La lezione segue i seguenti passaggi
-
Come usare
grep
e le sue varianti comeegrep
efgrep
. -
Come usare
sed
e le sue istruzioni interne per manipolare il testo. -
Esempi di applicazioni di espressioni regolari che utilizzano
grep
esed
.
Risposte agli Esercizi Guidati
-
Il comando
last
mostra un elenco degli ultimi utenti che hanno effettuato un accesso sul sistema, inclusi i loro IP di origine. Come verrebbe usato il comandoegrep
per filtrare l’output dilast
, mostrando solo le occorrenze di un indirizzo IPv4, scartando qualsiasi informazione aggiuntiva nella riga corrispondente?last -i | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
-
Quale opzione dovrebbe essere data a
grep
per filtrare correttamente l’output generato dal comandofind
eseguito con l’opzione-print0
?L’opzione
-z
o--null-data
, come infind . -print0 | grep -z expression
. -
Il comando
uptime -s
mostra l’ultima data in cui il sistema è stato acceso, come in2019-08-05 20:13:22
. Quale sarà il risultato del comandouptime -s | sed -e 's/(.*) (.*)/\1/'
?Si verificherà un errore. Per impostazione predefinita, le parentesi dovrebbero essere precedute da caratteri di escape per utilizzare i riferimenti a ritroso in
sed
. -
Quale opzione dovrebbe essere data a
grep
in modo che conti le linee corrispondenti invece di visualizzarle?L’opzione
-c
.
Risposte agli Esercizi Esplorativi
-
La struttura di base di un file HTML inizia con gli elementi
html
,head
ebody
, per esempio:<html> <head> <title>News Site</title> </head> <body> <h1>Headline</h1> <p>Information of interest.</p> </body> </html>
Descrivi come gli indirizzi potrebbero essere usati in
sed
per visualizzare solo l’elementobody
e il suo contenuto.Per mostrare solo
body
, gli indirizzi dovrebbero essere/<body>/,/<\/body>/
, come insed -n -e '/<body>/,/<\/body>/p'
. L’opzione-n
è data ased
quindi non stampa le righe per impostazione predefinita, da qui il comandop
alla fine dell’espressionesed
per stampare le righe corrispondenti. -
Quale espressione di
sed
rimuoverà tutti i tag da un documento HTML, mantenendo solo il testo visualizzato?L’espressione
sed
s/<[^>]*>//g
sostituirà qualsiasi contenuto racchiuso in<>
con una stringa vuota. -
I file con estensione
.ovpn
sono molto popolari per configurare i client VPN poiché contengono non solo le impostazioni, ma anche il contenuto delle chiavi e dei certificati per il client. Queste chiavi e certificati sono originariamente in file separati, quindi devono essere copiati nel file.ovpn
. Dato il seguente estratto di un modello.ovpn
:client dev tun remote 192.168.1.155 1194 <ca> ca.crt </ca> <cert> client.crt </cert> <key> client.key </key> <tls-auth> ta.key </tls-auth>
Supponendo che i file
ca.crt
,client.crt
,client.key
eta.key
si trovino nella directory corrente, come verrebbe modificata la configurazione del modello dised
per sostituire ogni nome di file con il suo contenuto?Il comando
sed -r -e 's/(^[^.]*)\.(crt|key)$/cat \1.\2/e' < client.template > client.ovpn
sostituisce qualsiasi riga che termini in
.crt
o.key
con il contenuto di un file il cui nome è uguale alla riga. L’opzione-r
dice ased
di usare espressioni regolari estese, mentree
alla fine dell’espressione dice ased
di sostituire le corrispondenze con l’output del comandocat \1.\2
. I riferimenti a ritroso\1
e\2
corrispondono al nome del file e all’estensione trovati nella corrispondenza.