  {"id":445,"date":"2016-02-24T15:48:28","date_gmt":"2016-02-24T14:48:28","guid":{"rendered":"http:\/\/www.gironi.it\/blog\/?p=445"},"modified":"2024-09-20T14:06:15","modified_gmt":"2024-09-20T13:06:15","slug":"awk-un-amico-per-aiutarci-con-i-log-files-e-non-solo","status":"publish","type":"post","link":"https:\/\/www.gironi.it\/blog\/awk-un-amico-per-aiutarci-con-i-log-files-e-non-solo\/","title":{"rendered":"AWK: un amico per aiutarci con i log files (e non solo)"},"content":{"rendered":"<h3>AWK &#8211; Un po&#8217; di storia&#8230;<\/h3>\n<p>La storia di AWK \u00e8 lunga, in termini informatici lunghissima. E&#8217; il 1977 quando Alfred Aho, Peter Weinberger e Brian Kerningham (dalle iniziali dei tre il suo nome) presentano questo anomalo linguaggio interpretato, utilissimo per processare files di testo strutturati e generare report.<!--more--><\/p>\n<figure id=\"attachment_450\" aria-describedby=\"caption-attachment-450\" style=\"width: 203px\" class=\"wp-caption alignleft\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-450 size-medium\" src=\"http:\/\/www.gironi.it\/blog\/wp-content\/uploads\/2016\/02\/awk-book-203x300.jpg\" alt=\"awk-book\" width=\"203\" height=\"300\" srcset=\"https:\/\/www.gironi.it\/blog\/wp-content\/uploads\/2016\/02\/awk-book-203x300.jpg 203w, https:\/\/www.gironi.it\/blog\/wp-content\/uploads\/2016\/02\/awk-book.jpg 337w\" sizes=\"auto, (max-width: 203px) 85vw, 203px\" \/><figcaption id=\"caption-attachment-450\" class=\"wp-caption-text\">la copertina del libro originale su AWK<\/figcaption><\/figure>\n<p>AWK \u00e8 un pi\u00f9 di un semplice tool e forse qualcosa meno di un completo linguaggio di programmazione, nel senso moderno del termine (anche se \u00e8 un completo linguaggio di programmazione). Mostra la sua piacevolezza e potenza come filtro in una <em>pipeline,&nbsp;<\/em>dove si fa preferire alla criptica sintassi di SED e consente di evitare di scomodare il Perl.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>AWK, nelle sue varianti (la pi\u00f9 diffusa \u00e8 quella a cura della Free Software Foundation, <a href=\"https:\/\/www.gnu.org\/software\/gawk\/\" target=\"_blank\" rel=\"noopener noreferrer\">GAWK<\/a>) \u00e8 disponibile praticamente per qualsiasi sistema operativo possiate immaginare. S\u00ec, anche il DOS.<\/p>\n<p>Ma cosa rende insieme unico, attraente e insieme cos\u00ec poco conosciuto questo strumento che ha per logo un simpatico pinguino, 14 anni prima di Linux?<\/p>\n<h3>La &#8220;strana&#8221; logica di AWK<\/h3>\n<p>Per spiegarlo inizier\u00f2 dal concetto di base su cui, a mio avviso, si fonda la corretta comprensione del linguaggio. No, non \u00e8 un esempio di &#8220;Hello World&#8221;&#8230;<\/p>\n<p>La logica di AWK \u00e8 semplice, ma potente. Come quasi tutti gli strumenti nati in ambito UNIX, AWK <strong>ragiona in termini di linee di testo<\/strong>. Processa una linea alla volta applicando delle&nbsp;regole, composte da:<\/p>\n<pre>pattern {azione}<\/pre>\n<p>sia il pattern che l&#8217;azione sono opzionali.<br \/>\nSe manca il pattern, l&#8217;azione viene applicata a tutti i record.<br \/>\nSe a mancare \u00e8 l&#8217;azione, il record che corrisponde al pattern \u00e8 scritto sullo standard output (quindi di default sullo schermo).<\/p>\n<p><strong>Quello che AWK fa, in pratica, \u00e8 leggere il testo una riga alla volta, separarlo in campi definiti da un delimitatore (modificabile), assegnare i valori a delle variabili predefinite ($1,$2,$3&#8230;) e applicare le regole indicate dal programmatore.<\/strong><\/p>\n<p>AWK pu\u00f2 ricevere il testo da processare attraverso una <em>pipe<\/em>, oppure pu\u00f2 presentarsi sotto forma di script, invocabile con awk -f nomescript.awk e processare il file o i files indicato\/i.<\/p>\n<h3>Un esempio vale mille parole<\/h3>\n<p>Complicato? Un esempio mostrer\u00e0 tutta la semplicit\u00e0 del linguaggio.<br \/>\nImmaginiamo di avere un file di testo chiamato amici.txt:<\/p>\n<pre>Aldo, 23\nCarlo, 28\nMario, 35\nPiero, 17\nStefano, 30\nUmberto, 29<\/pre>\n<p>Ok, l&#8217;esempio \u00e8 senza senso, ma serve solo per illustrare l&#8217;utilizzo di AWK&#8230;<\/p>\n<p>se io passo l&#8217;output di cat amici.txt tramite una pipe ad AWK in questo modo:<\/p>\n<pre>cat amici.txt | awk '\/Stefano\/ {print $2}'<\/pre>\n<p>oppure processo amici.txt direttamente cos\u00ec:<\/p>\n<pre> awk '\/Stefano\/ { print $2 }' amici.txt<\/pre>\n<p>il risultato a schermo sar\u00e0&#8230; 30<\/p>\n<p>Ricordate? pattern e azione. Se e quando AWK trova &#8220;Stefano&#8221; stampa il secondo campo, cio\u00e8 il numero 30. La virgola \u00e8 il delimitatore di default di AWK. Se avessi avuto come delimitatore il punto e virgola avrei potuto scrivere:<\/p>\n<pre>cat amici.txt | awk -F; \"\/Stefano\/&nbsp;{print $2}\"<\/pre>\n<p>Giochiamo un po&#8217;&#8230; se avessi scritto:<\/p>\n<pre>cat amici.txt | awk \"\/Stefano\/ {print $2, $1}\"<\/pre>\n<p>il risultato sarebbe stato:<\/p>\n<pre>30, Stefano<\/pre>\n<p>iniziate a capire l&#8217;utilit\u00e0 di questo strumento, ad esempio per processare al volo files csv?<\/p>\n<p>un po&#8217; di esempi banalissimi:<\/p>\n<pre>{print $1} stampa il primo campo di ogni linea di un file\n\n \/pippo\/   stampa tutte le linee che contengono pippo\n\nlenght($0) &lt; 40&nbsp;stampa tutte le linee che contengono meno di 40 caratteri<\/pre>\n<p>e via dicendo&#8230;<\/p>\n<p>Come dicevo, posso usare AWK in una pipe, ma posso anche scrivere dei veri e propri programmi, di maggiore complessit\u00e0.<\/p>\n<h3>Uno script AWK \u00e8 fatto&nbsp;di 3 parti (al massimo&#8230;)<\/h3>\n<p>Un programma AWK consta di tre parti: le assegnazioni e le operazioni per cos\u00ec dire preliminari, tipo l&#8217;assegnazione di variabili globali, che troveranno posto qui:<\/p>\n<pre>BEGIN {\n...\n}<\/pre>\n<p>(ovviamente questa sezione \u00e8 del tutto opzionale)<\/p>\n<p>poi seguiranno le istruzioni secondo la logica \/pattern\/ {azione} che abbiamo gi\u00e0 visto.<br \/>\nI pattern possono essere combinati con gli operatori booleani || (OR), &amp;&amp; (AND) e ! (NOT).<br \/>\nLe azioni consistono di uno o pi\u00f9 comandi, funzioni o assegnazione di variabili, separate da a capo o da punti e virgola e contenute dentro le parentesi graffe {}.<br \/>\nI comandi possono essere assegnazione di variabili (o array), comandi di stampa, funzioni interne, comandi per controllare il flusso dell&#8217;operazione.<\/p>\n<p>e per finire, anch&#8217;esso opzionale:<\/p>\n<pre>END {\n...\n}<\/pre>\n<p>dove andr\u00f2, ad esempio, a stampare il risultato finale di una mia elaborazione (potrei aver sommato tutti i valori presenti in $2 di tutte le righe in una variabile e dentro END andr\u00f2 a stampare, alla fine, il valore totale di quella variabile&#8230;).<\/p>\n<p>Se salvo il mio script con un nome, ad esempio pippo.awk, posso eseguirlo con:<\/p>\n<pre>awk -f pippo.awk\n\n<\/pre>\n<p>o pi\u00f9 comodamente iniziando il mio script con:<\/p>\n<pre>  #!\/usr\/bin\/awk -f<\/pre>\n<p>e poi rendendolo&nbsp;eseguibile.<\/p>\n<p>Le variabili possono essere assegnate nel modo pi\u00f9 semplice possibile:<br \/>\nPIPPO = &#8220;dsajsakdsk&#8221;<\/p>\n<p>Gli arrays possono essere creati con la funzione split:<\/p>\n<pre>split (stringa,array[,separatore])<\/pre>\n<p>&#8230;il resto lo lascio alla vostra fantasia!<\/p>\n<hr>\n<h4>In libreria, per approfondire<\/h4>\n<div style=\"float: left;padding-right:20px\"><iframe loading=\"lazy\" style=\"width: 120px; height: 240px;\" src=\"https:\/\/rcm-eu.amazon-adsystem.com\/e\/cm?ref=qf_sp_asin_til&amp;t=consulenzeinf-21&amp;m=amazon&amp;o=29&amp;p=8&amp;l=as1&amp;IS2=1&amp;asins=B004D4Y302&amp;linkId=3900986c421b778594422cadb15bd281&amp;bc1=FFFFFF&amp;lt1=_blank&amp;fc1=333333&amp;lc1=0066C0&amp;bg1=FFFFFF&amp;f=ifr\" width=\"300\" height=\"150\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><br \/>\n<\/iframe><\/div>\n<div style=\"float: left;\"><iframe loading=\"lazy\" style=\"width: 120px; height: 240px;\" src=\"https:\/\/rcm-eu.amazon-adsystem.com\/e\/cm?ref=qf_sp_asin_til&amp;t=consulenzeinf-21&amp;m=amazon&amp;o=29&amp;p=8&amp;l=as1&amp;IS2=1&amp;asins=B00U8232XM&amp;linkId=31b83d17e2c197ee14c7b1f549d033ab&amp;bc1=FFFFFF&amp;lt1=_blank&amp;fc1=333333&amp;lc1=0066C0&amp;bg1=FFFFFF&amp;f=ifr\" width=\"300\" height=\"150\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><br \/>\n<\/iframe><\/div>\n","protected":false},"excerpt":{"rendered":"<p>AWK &#8211; Un po&#8217; di storia&#8230; La storia di AWK \u00e8 lunga, in termini informatici lunghissima. E&#8217; il 1977 quando Alfred Aho, Peter Weinberger e Brian Kerningham (dalle iniziali dei tre il suo nome) presentano questo anomalo linguaggio interpretato, utilissimo per processare files di testo strutturati e generare report.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","footnotes":""},"categories":[929,751],"tags":[931,933,889,935],"class_list":["post-445","post","type-post","status-publish","format-standard","hentry","category-awk-it","category-linux-it","tag-awk-it","tag-riga-di-comando-it","tag-script-it","tag-unix-it"],"lang":"it","translations":{"it":445},"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false},"uagb_author_info":{"display_name":"paolo","author_link":"https:\/\/www.gironi.it\/blog\/author\/paolo\/"},"uagb_comment_info":0,"uagb_excerpt":"AWK &#8211; Un po&#8217; di storia&#8230; La storia di AWK \u00e8 lunga, in termini informatici lunghissima. E&#8217; il 1977 quando Alfred Aho, Peter Weinberger e Brian Kerningham (dalle iniziali dei tre il suo nome) presentano questo anomalo linguaggio interpretato, utilissimo per processare files di testo strutturati e generare report.","_links":{"self":[{"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/posts\/445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/comments?post=445"}],"version-history":[{"count":1,"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/posts\/445\/revisions"}],"predecessor-version":[{"id":3183,"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/posts\/445\/revisions\/3183"}],"wp:attachment":[{"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/media?parent=445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/categories?post=445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gironi.it\/blog\/wp-json\/wp\/v2\/tags?post=445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}