Grep and sed Demystified

Grep. Lo senti molto. Vedete quei criptici membri dell'IT che digitano il comando, amministratori di sistema che lo citano di passaggio, lo vedete persino in alcuni script di shell. Sembra una di quelle cose che esiste, ma non è pensata per te. Questo articolo cambierà - spiegheremo e daremo un'occhiata a grep (e al suo amico meno famoso sed) in questa nuova versione di OS X Demystified.


introduzione

grep

Grep è un'utilità della riga di comando per cercare e filtrare una sorta di input testuale in base ai parametri che lo alimentano

Grep è un'utilità della riga di comando per cercare e filtrare una sorta di input testuale in base ai parametri che lo alimentano. In altre parole, funziona nel Terminale (Applicazioni → Utility → Terminale), ed è usato esclusivamente digitando i comandi. Ci sono, naturalmente, wrapper GUI che aiutano un po ', ma nessuno è potente o versatile come l'utilizzo da riga di comando di bare bones, quindi è quello su cui ci concentreremo.

È tutto molto bello, ma cosa fa in realtà? Quanto sopra sembra troppo vago? Ecco un esempio. Di 'che hai un blocco di testo in un file chiamato jungle.txt con cinque righe:

Un leone dorme nella giungla Un leone dorme stanotte Una tigre si risveglia nella palude Il pappagallo osserva Wimoweh, wimoweh, wimoweh, wimoweh

Per trovare la linea che contiene la parola tigre, usiamo grep in questo modo:

grep tiger jungle.txt

Il risultato che ci viene dato è:

"Una tigre si risveglia nella palude"

Ok, è chiaro, giusto? Facciamo un passo indietro però.

Aggiornamento di Grep

A quanto pare Mac grep è più lento di GNU grep, quindi facciamo prima un upgrade. Per installare un grep più veloce, inserire quanto segue in Terminale e premere accedere:

brew install https://raw.github.com/Homebrew/homebrew-dupes/master/grep.rb

Si noti che è necessario aver installato Homebrew per poterlo fare e per sapere come installare Homebrew, vedere il mio precedente articolo.

Una vasta gamma di geeklet si basa spesso su grep per recuperare i dati da file di testo di grandi dimensioni o siti Web raccolti

Cosa abbiamo realizzato eseguendo questo aggiornamento? Bene, molte app usano lo strumento nativo di grep installato per funzionare. Ad esempio, una vasta gamma di geeklet si affida spesso a grep per recuperare i dati da file di testo di grandi dimensioni o da siti Web raccolti. così, tutti i tuoi geeklet che utilizzano grep ora saranno molte volte più veloci nelle loro parti più avide. Inoltre, a volte potresti aver bisogno di grep qualche tipo di registro degli errori (diciamo che hai un enorme registro degli errori da un'applicazione e il servizio di supporto dell'app ti dice di incollarli "grep port-1723"). Se il registro contiene milioni di righe di codice, è possibile risparmiare un sacco di tempo utilizzando questo grep molto più veloce.

Una volta che Homebrew ha installato il tuo nuovo grep, prova a fare quanto segue se hai creato i file. In caso contrario, andare avanti e renderli, quindi eseguire il comando per assicurarsi che tutto funzioni.

grep tiger jungle.txt

Sed

Sed è un Stream Editor. In parole povere, prende l'input, lo modifica e genera il contenuto modificato. Che sia la modifica in un file o che venga alimentata direttamente da Terminal è completamente irrilevante per sed - ha una funzione altamente avanzata e configurabile, e la esegue al meglio delle sue capacità.

Sed prende del testo, un comando su come cambiarlo e produce un output modificato

Quindi dove viene usato sed? Modifica dei contenuti dei file e simili, ovviamente, ma succede che funzioni perfettamente alla pari con grep. Vediamo prima alcuni esempi di pura sed, però. Digitare quanto segue nel terminale:

echo "Ciao"

e premere invio. Il terminale dice ciao. Adesso scrivi

echo "Ciao" | sed 's / Hell / Heaven /'

e premere invio. Dovresti vedere "Heaveno". Cosa è appena successo? Vedi, sed opere prendendo due argomenti. Il primo è il feed, l'input, e il secondo è una stringa (puoi vedere che è una stringa perché è quotata) che indica quali azioni eseguire sul primo argomento. Nel nostro caso è questo:

  • s (sostituto)
  • / (delimitatore - nel nostro caso barra inversa, vedere il prossimo paragrafo per le alternative)
  • Inferno (modello di espressioni regolari da cercare)
  • Heaven (stringa di sostituzione)

Il secondo elemento della lista menziona alternative al delimitatore di barre in avanti; a volte sono molto utili a causa, ad esempio, della scrittura di URL o percorsi di file. Prendi ad esempio l'url myfolder / MySubFolder / myfile. Se mettiamo questo in sed per sostituirlo con myotherfolder / myotherfile, il parametro sarebbe così: s / myfolder / MySubFolder / myfile / myotherfolder / myotherfile / che è solo un grande sacco di sciocchezze - sed non si può sapere quale di questi frammenti è il regexp e quale è la stringa sostitutiva. Pertanto, avremmo bisogno di fuga il forwardslashes nel nostro filepath con backslash, quindi ogni forwardslash nel percorso si trasformerebbe in \ /. Immagino che tu possa vedere il problema. Il nuovo parametro sed si presenta così:

sed 's / myfolder \ / mysubfolder \ / myfile / myotherfolder \ / myotherfile /'

Questo formato appena leggibile è chiamato "picchetto", e per evitarlo, sed supporta diversi delimitatori come il carattere di sottolineatura (_), i due punti (:) e il tubo (|). Ad esempio, se volessimo usare il carattere pipe come delimitatore, avremmo il seguente risultato:

sed 's | myfolder / mysubfolder / myfile | myotherfolder / myotherfile |'

Molto meglio, no?

Un'altra cosa, però. Abbiamo detto che sed prende due argomenti, eppure ne diamo sempre uno solo - subito dopo sed comando. Questo è dovuto al carattere della pipa dopo il nostro eco comando. La pipe serve come mezzo per indirizzare l'output dell'operando di sinistra nell'input dell'operando di destra. Nel nostro caso, il personaggio della pipa ha detto al sed programma "Prendi come input qualunque cosa tu abbia da qualunque cosa ci sia sul lato sinistro di me". sed non ha idea che si tratti di eco - non ha bisogno di sapere. Tutto ciò che sa è che sta prendendo l'input del testo. Discutere la pipeline in modo più dettagliato di questo esula dallo scopo di questo articolo, ma sentiti libero di leggere se sei interessato.

La pipe serve come mezzo per indirizzare l'output dell'operando di sinistra nell'input dell'operando di destra.

Quindi, come lo combiniamo con grep? È esattamente lo stesso. Prendendo il nostro esempio precedente, inseriamo quanto segue nel terminale.

grep tiger jungle.txt | sed 's / palude / deserto /'

e otteniamo l'output

"Una tigre si sveglia nel deserto"

Ora diamo un'occhiata a un caso d'uso del mondo reale.


Applicazione del mondo reale

Per la nostra "dissezione" prenderemo il comando grep + sed di un popolare geeklet meteo e lo spiegheremo un po 'alla volta. Vai avanti e scarica il geeklet di esempio. Una volta scaricato, aprilo con un editor di testo di qualsiasi tipo. Noterai che non è più di un file XML. Se non hai esperienza con XML, non preoccuparti: Josh ha già realizzato un articolo straordinario su Geektool e i suoi dettagli. Non avremo a che fare con il nocciolo duro di tutto ciò oggi. Invece, concentriamoci sulla parte tra il tags:

 curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Condizioni correnti: | C// '-e' s /// '-e' s /<\/b>// '-e' s /
// '-e' s /// '-e' s /<\/description>//'

Questo pasticcio criptico è un semplice comando Terminale - niente di più. Puoi persino incollarlo nel terminale e otterrai le condizioni meteorologiche per Makati City nelle Filippine, che l'autore originale ha impostato per recuperare. Il geeklet dice a Geektool di eseguire il suddetto comando e prendere l'output ottenuto eseguendolo. Diamo un'occhiata a questo, segmento di tubo per segmento di tubo e spieghiamo in dettaglio:

curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c"

arricciare è uno strumento per il trasferimento di dati con una sintassi URL. Ciò significa che può andare a un URL e recuperare i dati da esso.

Curl è uno strumento utilizzato per il trasferimento di dati con una sintassi URL sulla riga di comando

Se incolli l'URL tra virgolette nel tuo browser (o fai clic qui), noterai che ricevi un file XML da Yahoo! - dispongono di un servizio di condizioni meteo in tempo reale a cui è possibile accedere e recuperare facilmente i dati. Questa è esattamente la stessa cosa che ottieni quando tu arricciare essa; solo al posto del browser, l'input viene inviato al terminale. Il --silenzioso flag dice a curl di essere tranquillo su progresso, stato ed errori, in modo che l'unico risultato che otteniamo sia l'output di cui abbiamo bisogno (o nulla, se fallisce).

grep -E '(Condizioni correnti: | C 

Segue il carattere della pipa, ovvero l'output di arricciare viene inviato in grep come input. Grep riceve questo file XML scaricato in formato testo ed esegue una ricerca su di esso con il file -E bandiera, che significa espressione regolare estesa. Il valore che sta cercando è la stringa Condizioni attuali: o C (il carattere pipe all'interno di un ereg significa "o"). Per ulteriori chiarimenti, se hai digitato quanto segue nel nostro esempio precedente:

grep -E '(tiger | weh)' jungle.txt

otterresti

Una tigre si risveglia nella palude Wimoweh, wimoweh, wimoweh, wimoweh

perché restituisce tutte le linee che contengono "tigre" o "weh".

Quindi, se eseguiamo questi due primi segmenti di tubi insieme in questo modo:

curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Condizioni correnti: | C 

otteniamo il seguente:

Condizioni attuali:
Foschia, 23 C

Ma vogliamo solo ottenere "Haze, 23 C". Qui è dove sed entra. Sostituiamo semplicemente tutto ciò che non vogliamo con una stringa vuota (nulla) efficacemente cancellandola.

sed -e 's / Current Conditions: //' -e 's /
// '-e' s /// '-e' s /<\/b>// '-e' s /
// '-e' s /// '-e' s /<\/description>//'

Il -e la bandiera è l'abbreviazione di --espressione = e ci permette di concatenare più cose sed comandi. Pertanto, per prima cosa sostituiamo la stringa "Condizioni attuali:" con niente, seguita dalla sostituzione
con niente, ecc. fino a raggiungere la possibile fine della linea ().

Alla fine, tutto ciò che rimane è "Haze, 23 C".

Dovrei menzionare che il geeklet che abbiamo usato come esempio avrebbe potuto essere fatto molto meglio, ma la pura complessità del comando usato mi è sembrata un'ottima opportunità per coprire più esempi contemporaneamente. Ad esempio, l'autore avrebbe potuto semplicemente recuperare la riga contenente "Condizioni attuali:" e la linea dopo di essa con il -A 1 combinazione di flag, senza fare affidamento sul simbolo della temperatura (in questo caso, ci affidiamo a Celsius, ma se volessimo Fahrenheit? C la ricerca di grep fallirebbe). Ciò nondimeno, l'esempio ha avuto uno scopo, e questo ti ha introdotto nel meraviglioso mondo di grep e sed.


Altre risorse

Mentre si insegnano le espressioni regolari avanzate e la funzionalità di grep, arricciatura e sed più profonda è al di fuori degli scopi di questo articolo (e di questo sito Web), non esitare a consultare le seguenti risorse se desideri saperne di più.

  • Guida di Sed
  • Guida per principianti a grep
  • Esempi pratici di comando Unix Grep
  • Grep documentation presso IBM
  • Documentazione di arricciatura
  • Espressioni regolari

Conclusione

Adesso conosci le basi di grep, sed e persino arricciare. Anche se questo corso accelerato era abbastanza lontano da renderti un esperto, ci auguriamo che sia stato almeno sufficiente per farti interessare a provare la raccolta e l'interrogazione dei dati. Per lo meno, lunedì è qualcosa di cui parlare intorno al refrigeratore d'acqua.

Spero che ti sia piaciuto, e se sei pronto per una sfida, prova a riscrivere il Geeklet per non solo essere agnostico della temperatura, ma anche per capire da solo la posizione dell'utente, senza dover alterare manualmente 'parametro in Yahoo! URL.