<!--
     The FreeBSD Italian Documentation Project

     $FreeBSD: doc/it_IT.ISO8859-15/books/unix-introduction/text-processing/chapter.sgml,v 1.1 2003/03/19 18:46:43 trhodes Exp $
-->

<chapter id="text-processing">
  <title>Manipolazione del testo</title>

  <sect1 id="text-processing-reg-exp-syntax">
    <title>Sintassi delle espressioni regolari</title>

    <para>Alcuni programmi di manipolazione del testo come
      &man.grep.1;, &man.egrep.1;, &man.sed.1;, &man.awk.1; e &man.vi.1;
      consentono di ricercare uno schema (pattern) piuttosto che una stringa
      fissa.  Questi schemi testuali sono conosciuti come <emphasis>espressioni
        regolari</emphasis>.  Si pu&ograve; formare un'espressione regolare
      combinando caratteri normali con caratteri speciali, anche conosciuti
      come <emphasis>meta-caratteri</emphasis>, secondo le successive regole.
      Con queste espressioni regolari si pu&ograve; <emphasis>confrontare uno
        schema</emphasis> su dati testuali.  Le espressioni regolari si
      presentano in tre diverse forme:</para>

    <informaltable frame="none">
      <tgroup cols="2">
        <colspec colwidth="1.5in">

        <tbody>
          <row>
            <entry><emphasis>Ancoraggi</emphasis></entry>

            <entry>legano lo schema a una posizione sulla linea</entry>
          </row>

          <row>
            <entry><emphasis>Serie di caratteri</emphasis></entry>

            <entry>indicano un carattere in una singola posizione</entry>
          </row>

          <row>
            <entry><emphasis>Modificatori</emphasis></entry>

            <entry>specificano quante volte ripetere l'espressione
              precedente</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>

    <para>Segue la sintassi delle espressioni regolari.  Alcuni programmi
      accettano tutte queste sintassi, altri ne accettano solo alcune:</para>

    <informaltable frame="none">
      <tgroup cols="2">
        <colspec colwidth="1in">

        <tbody>
          <row>
            <entry><emphasis>.</emphasis></entry>

            <entry>indica <emphasis>un</emphasis> singolo carattere eccetto
              quello di newline</entry>
          </row>

          <row>
            <entry><emphasis>*</emphasis></entry>

            <entry>indica <emphasis>zero o pi&ugrave;</emphasis> istanze del
              singolo carattere (o meta-carattere) che lo precede</entry>
          </row>

          <row>
            <entry><emphasis>[<replaceable>abc</replaceable>]</emphasis></entry>

            <entry>indica un carattere tra quelli racchiusi</entry>
          </row>

          <row>
            <entry><emphasis>[<replaceable>a-d</replaceable>]</emphasis></entry>

            <entry>indica un carattere tra quelli compresi nel range</entry>
          </row>

          <row>
            <entry><emphasis>[^<replaceable>exp</replaceable>]</emphasis></entry>

            <entry>indica un carattere tra quelli <emphasis>non</emphasis>
              inclusi nell'espressione</entry>
          </row>

          <row>
            <entry><emphasis>^<replaceable>abc</replaceable></emphasis></entry>

            <entry>l'espressione regolare deve iniziare all'<emphasis>inizio
              della linea</emphasis> (Ancoraggio)</entry>
          </row>

          <row>
            <entry><emphasis><replaceable>abc</replaceable>$</emphasis></entry>

            <entry>l'espressione regolare deve finire alla <emphasis>fine della
              linea</emphasis> (Ancoraggio)</entry>
          </row>

          <row>
            <entry><emphasis>\</emphasis></entry>

            <entry>tratta il carattere successivo letteralmente.  Viene
              normalmente usato per mantenere inalterato il significato di un
              carattere speciale come . e *.</entry>
          </row>

          <row>
            <entry><emphasis>\{<replaceable>n</replaceable>,<replaceable>m</replaceable>\}</emphasis></entry>

            <entry>confronta l'espressione regolare precedente un numero minimo
              <replaceable>n</replaceable> di volte e un numero massimo
              <replaceable>m</replaceable> di volte
              (<replaceable>n</replaceable> e <replaceable>m</replaceable>
              possono assumere valori tra 0 e 255).  I simboli \{ e \}
              dovrebbero essere intesi come singoli operatori.  In questo caso
              il simbolo \ che precede le parentesi non &egrave; il carattere di
              escape, ma assume un nuovo significato.</entry>
          </row>

          <row>
            <entry><emphasis>\&lt;<replaceable>abc</replaceable>\&gt;</emphasis></entry>

            <entry>confronta l'espressione regolare racchiusa trattandola come
              una singola parola.  I limiti della parola sono definiti iniziando
              con un newline o qualche altra cosa, eccetto una lettera, una
              cifra o un underscore ( _ ), e finendo con la stessa cosa o con un
              carattere di fine linea.  Ancora, i simboli \&lt; e \&gt;
              dovrebbero essere intesi come singoli operatori.</entry>
          </row>

          <row>
            <entry><emphasis>\(<replaceable>abc</replaceable>\)</emphasis></entry>

            <entry>salva lo schema racchiuso in un buffer.  Possono essere
              salvati per ogni linea fino a nove schemi.  &Egrave; possibile
              riferirsi a questi schemi tramite la combinazione di caratteri
              \<replaceable>n</replaceable>.  Ancora una volta i simboli \( e \)
              dovrebbero essere intesi come singoli operatori.</entry>
          </row>

          <row>
            <entry><emphasis>\<replaceable>n</replaceable></emphasis></entry>

            <entry>dove <replaceable>n</replaceable> varia tra 1 e 9.  Confronta
              l'<replaceable>n-sima</replaceable> espressione precedentemente
              salvata per la linea corrente.  Le espressioni sono numerate
              partendo da sinistra.  Il simbolo \<replaceable>n</replaceable>
              dovrebbe essere inteso come un singolo operatore.</entry>
          </row>

          <row>
            <entry><emphasis>&amp;</emphasis></entry>

            <entry>mostra lo schema di ricerca precedente (usato al posto della
              stringa)</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>

    <para>Ci sono alcuni meta-caratteri usati solamente da &man.awk.1; e
      &man.egrep.1;.  Questi sono:</para>

    <informaltable frame="none">
      <tgroup cols="2">
        <colspec colwidth="0.5in">

        <tbody>
          <row>
            <entry><emphasis>+</emphasis></entry>

            <entry>confronta una o pi&ugrave; delle espressioni precedenti (a
              questo simbolo)</entry>
          </row>

          <row>
            <entry><emphasis>?</emphasis></entry>

            <entry>confronta zero o alcune delle espressioni precedenti (a
              questo simbolo)</entry>
          </row>

          <row>
            <entry><emphasis>|</emphasis></entry>

            <entry>separatore.  Confronta sia l'espressione precedente (a questo
              simbolo) sia quella seguente</entry>
          </row>

          <row>
            <entry><emphasis>( )</emphasis></entry>

            <entry>raggruppa le espressioni regolari all'interno delle parentesi
              e applica una serie di confronti</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>

    <para>Alcuni esempi di <emphasis>espressioni regolari</emphasis> comuni
      sono:</para>

    <informaltable frame="none">
      <tgroup cols="2">
        <colspec colwidth="2in">

        <thead>
          <row>
            <entry>espressione regolare</entry>

            <entry>indica</entry>
          </row>
        </thead>

        <tbody>
          <row>
            <entry>cat</entry>

            <entry>la stringa <emphasis>cat</emphasis></entry>
          </row>

          <row>
            <entry>.at</entry>

            <entry>alcune occorrenze di un carattere precedente ad
              <emphasis>at</emphasis>, come cat, rat, mat, bat, fat, hat</entry>
          </row>

          <row>
            <entry>xy*z</entry>

            <entry>alcune occorrenze di un <emphasis>x</emphasis>, seguite da
              zero o pi&ugrave; <emphasis>y</emphasis> e seguite da una
              <emphasis>z</emphasis>.</entry>
          </row>

          <row>
            <entry>^cat</entry>

            <entry><emphasis>cat</emphasis> all'inizio della linea</entry>
          </row>

          <row>
            <entry>cat$</entry>

            <entry><emphasis>cat</emphasis> alla fine della linea</entry>
          </row>

          <row>
            <entry>\*</entry>

            <entry>alcune occorrenze di un asterisco</entry>
          </row>

          <row>
            <entry>[cC]at</entry>

            <entry><emphasis>cat</emphasis> o <emphasis>Cat</emphasis></entry>
          </row>

          <row>
            <entry>[^a-zA-Z]</entry>

            <entry>alcune occorrenze di caratteri non alfabetici</entry>
          </row>

          <row>
            <entry>[0-9]$</entry>

            <entry>alcune linee che finiscono con un numero</entry>
          </row>

          <row>
            <entry>[A-Z][A-Z]*</entry>

            <entry>una o pi&ugrave; lettere maiuscole</entry>
          </row>

          <row>
            <entry>[A-Z]*</entry>

            <entry>zero o alcune lettere maiuscole (in altre parole,
              qualcosa)</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>
  </sect1>

  <sect1 id="text-processing-commands">
    <title>Comandi di manipolazione del testo</title>

    <table frame="all" id="text-processing-table-commands">
      <title>Comandi di manipolazione del testo</title>

      <tgroup cols="2">
        <colspec colwidth="4.5in">

        <thead>
          <row>
            <entry align="center">Comando/Sintassi</entry>

            <entry align="center">Cosa fa</entry>
          </row>
        </thead>

        <tbody>
          <row>
            <entry><command>awk/nawk [<replaceable>opzioni</replaceable>]
                <replaceable>file</replaceable></command></entry>

            <entry>esamina gli schemi (pattern) all'interno di un file ed
              elabora i risultati</entry>
          </row>

          <row>
            <entry><command>grep/egrep/fgrep
                [<replaceable>opzioni</replaceable>]
                '<replaceable>stringa di ricerca</replaceable>'
                <replaceable>file</replaceable></command></entry>

            <entry>ricerca nell'argomento (in questo caso probabilmente un
              file) tutte le occorrenze della stringa di ricerca e le
              elenca</entry>
          </row>

          <row>
            <entry><command>sed [<replaceable>opzioni</replaceable>]
                <replaceable>file</replaceable></command></entry>

            <entry>editor di flusso per manipolare file da uno script o da
              linea di comando</entry>
          </row>
        </tbody>
      </tgroup>
    </table>

    <sect2 id="text-processing-commands-grep">
      <title>grep</title>

      <para>Questa sezione fornisce un'introduzione all'uso delle
        <emphasis>espressioni regolari</emphasis> con &man.grep.1;.</para>

      <para>L'utility &man.grep.1; viene usata per ricercare espressioni
        regolari comuni che si presentano nei file Unix.  Le espressioni
        regolari, come quelle viste in precedenza, sono meglio specificate
        all'interno di apostrofi (o caratteri di quoting singoli) quando
        usate con l'utility &man.grep.1;.  L'utility &man.egrep.1; fornisce
        una capacit&agrave; di ricerca attraverso un set esteso di
        meta-caratteri.  La sintassi dell'utility &man.grep.1;, alcune delle
        possibili opzioni e alcuni semplici esempi sono mostrati di
        seguito.</para>

      <para><emphasis>Sintassi</emphasis></para>

      <para><command>grep [<replaceable>opzioni</replaceable>]
          <replaceable>expreg</replaceable>
          [<replaceable>file</replaceable>]</command></para>

      <para><emphasis>Opzioni generali</emphasis></para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="0.5in">

          <tbody>
            <row>
              <entry><option>-i</option></entry>

              <entry>ignora la differenza tra caratteri maiuscoli e
                minuscoli</entry>
            </row>

            <row>
              <entry><option>-c</option></entry>

              <entry>riporta solamente la somma del numero di linee contenenti
                le corrispondenze, non le corrispondenze stesse</entry>
            </row>

            <row>
              <entry><option>-v</option></entry>

              <entry>inverte la ricerca, visualizzando solo le linee senza
                corrispondenza</entry>
            </row>

            <row>
              <entry><option>-n</option></entry>

              <entry>mostra un numero di linea insieme alla linea su cui
                &egrave; stata trovata una corrispondenza</entry>
            </row>

            <row>
              <entry><option>-s</option></entry>

              <entry>lavora in silenzio, riportando solo lo stato
                finale:</entry>
            </row>

            <row>
              <entry></entry>

              <entry>0, per corrispondenze trovate</entry>
            </row>

            <row>
              <entry></entry>

              <entry>1, per nessuna corrispondenza</entry>
            </row>

            <row>
              <entry></entry>

              <entry>2, per errori</entry>
            </row>

            <row>
              <entry><option>-l</option></entry>

              <entry>elenca i nomi dei file, ma non le linee, nei quali sono
                state trovate corrispondenze</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para><emphasis>Esempi:</emphasis></para>

      <para>Si consideri il seguente file:</para>

      <screen>{Unix prompt 5} <userinput>cat num.list</userinput>
 1      15 fifteen
 2      14 fourteen
 3      13 thirteen
 4      12 twelve
 5      11 eleven
 6      10 ten
 7       9 nine
 8       8 eight
 9       7 seven
10       6 six
11       5 five
12       4 four
13       3 three
14       2 two
15       1 one</screen>

      <para>Ecco alcuni esempi di &man.grep.1; usando tale file.
        Nel primo si ricerca il numero <emphasis>15</emphasis>:</para>

      <screen>{Unix prompt 6} <userinput>grep '15' num.list</userinput>
 1      15 fifteen
15       1 one</screen>

      <para>Ora si usa l'opzione <option>-c</option> per contare il numero di
        linee che corrispondono al precedente criterio di ricerca:</para>

      <screen>{Unix prompt 7} <userinput>grep -c '15' num.list</userinput>
2</screen>

      <para>Qui la ricerca &egrave; pi&ugrave; generale: si selezionano tutte le
        linee che contengono il carattere <emphasis>1</emphasis> seguito da un
        <emphasis>1</emphasis> o un <emphasis>2</emphasis> o un
        <emphasis>5</emphasis>:</para>

      <screen>{Unix prompt 8} <userinput>grep '1[125]' num.list</userinput>
 1      15 fifteen
 4      12 twelve
 5      11 eleven
11       5 five
12       4 four
15       1 one</screen>

      <para>Ora si ricercano tutte le linee che <emphasis>iniziano</emphasis>
        con uno <emphasis>spazio</emphasis>:</para>

      <screen>{Unix prompt 9} <userinput>grep '^ ' num.list</userinput>
 1      15 fifteen
 2      14 fourteen
 3      13 thirteen
 4      12 twelve
 5      11 eleven
 6      10 ten
 7       9 nine
 8       8 eight
 9       7 seven</screen>

      <para>Ora tutte le linee che <emphasis>non iniziano</emphasis> con uno
        <emphasis>spazio</emphasis>:</para>

      <screen>{Unix prompt 10} <userinput>grep '^[^ ]' num.list</userinput>
10       6 six
11       5 five
12       4 four
13       3 three
14       2 two
15       1 one</screen>

      <para>L'ultimo esempio pu&ograve; anche essere realizzato usando l'opzione
        <option>-v</option> insieme all stringa di ricerca originale,
        esempio:</para>

      <screen>{Unix prompt 11} <userinput>grep -v '^ ' num.list</userinput>
10       6 six
11       5 five
12       4 four
13       3 three
14       2 two
15       1 one</screen>

      <para>Ora si ricercano tutte le linee che <emphasis>iniziano</emphasis>
        con carattere <emphasis>compreso</emphasis> tra <emphasis>1</emphasis> e
        <emphasis>9</emphasis>:</para>

      <screen>{Unix prompt 12} <userinput>grep '^[1-9]' num.list</userinput>
10       6 six
11       5 five
12       4 four
13       3 three
14       2 two
15       1 one</screen>

      <para>In questo esempio si ricercano alcune istanze di
        <emphasis>t</emphasis> seguite da <emphasis>zero o alcune</emphasis>
        occorrenze di <emphasis>e</emphasis>:</para>

      <screen>{Unix prompt 13} <userinput>grep 'te*' num.list</userinput>
 1      15 fifteen
 2      14 fourteen
 3      13 thirteen
 4      12 twelve
 6      10 ten
 8       8 eight
13       3 three
14       2 two</screen>

      <para>In questo esempio si ricercano alcune istanze di
        <emphasis>t</emphasis> seguite da <emphasis>una o alcune</emphasis>
        occorrenze di e:</para>

      <screen>{Unix prompt 14} <userinput>grep 'tee*' num.list</userinput>
1      15 fifteen
2      14 fourteen
3      13 thirteen
6      10 ten</screen>

      <para>Si pu&ograve; prendere il proprio input da un programma,
        anzich&egrave; da un file.  Qui si riportano alcune linee di output del
        comando &man.who.1; che iniziano con la lettera
        <emphasis>l</emphasis>.</para>

      <screen>{Unix prompt 15} <userinput>who | grep '^l'</userinput>
lcondron ttyp0 Dec 1 02:41 (lcondron-pc.acs.)</screen>
    </sect2>

    <sect2 id="text-processing-commands-sed">
      <title>sed</title>

      <para>L'editor di flusso non interattivo &man.sed.1; manipola un
        flusso di input, linea per linea, creando specifici cambiamenti e
        mandando il risultato su standard output.</para>

      <para><emphasis>Sintassi</emphasis></para>

      <para><command>sed [<replaceable>opzioni</replaceable>]
          <replaceable>comando_di_editing</replaceable>
          [<replaceable>file</replaceable>]</command></para>

      <para>Il formato per i comandi di editing &egrave;:</para>

      <para><command>[<replaceable>indirizzo1</replaceable>[,<replaceable>indirizzo2</replaceable>]]
          [<replaceable>funzione</replaceable>]
          [<replaceable>argomenti</replaceable>]</command></para>

      <para>dove gli indirizzi sono facoltativi e possono essere separati dalla
        funzione tramite spazi o tab.  La funzione &egrave; obbligatoria.
        L'argomento pu&ograve; essere facoltativo o obbligatorio a seconda della
        funzione usata.</para>

      <para>Gli <emphasis>indirizzi di linea numerati</emphasis> sono numeri
        decimali di linea che partono dalla prima linea di input e si
        incrementano di uno per ogni linea.  Se vengono stabiliti pi&ugrave;
        file di input il contatore continua cumulativamente attraverso i file.
        L'ultima linea di input pu&ograve; essere specificata con il carattere
        $.</para>

      <para>Gli <emphasis>indirizzi di contesto</emphasis> sono schemi di
        espressioni regolari racchiusi tra caratteri di slashe (/).</para>

      <para>I comandi possono avere 0, 1 o 2 indirizzi separati da virgola con i
        seguenti effetti:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="2in">

          <thead>
            <row>
              <entry># indirizzi</entry>

              <entry>linee considerate</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>0</entry>

              <entry>tutte le linee di input</entry>
            </row>

            <row>
              <entry>1</entry>

              <entry>solamente le linee che corrispondono agli indirizzi
                specificati</entry>
            </row>

            <row>
              <entry>2</entry>

              <entry>dalla prima linea che corrisponde al primo indirizzo fino
                alla linea che corrisponde al secondo indirizzo, inclusa.  Il
                processo viene ripetuto per le linee interne.</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>Le <emphasis>funzioni di sostituzione</emphasis> permettono di
        ricercare contesti e sono specificate nella forma:</para>

      <para><command>s/<replaceable>schema_espressione_regolare</replaceable>/<replaceable>stringa_di_rimpiazzo</replaceable>/<replaceable>flag</replaceable></command></para>

      <para>e possono essere quotate con caratteri di quoting singoli (') se
        sono specificate opzioni o funzioni aggiuntive.  Questi schemi sono
        identici agli indirizzi di contesto, eccetto che, mentre questi sono
        normalmente chiusi tra slashe (/), nelle funzioni sono permessi alcuni
        normali caratteri per specificare i delimitatori, oltre a newline e
        spazio.  La stringa di rimpiazzo non &egrave; uno schema di
        espressione regolare; qui i caratteri non hanno significati speciali,
        fatta eccezione di:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="0.5in">

          <tbody>
            <row>
              <entry><emphasis>&amp;</emphasis></entry>

              <entry>che sostituisce tale simbolo con la stringa
                <replaceable>schema_espressione_regolare</replaceable></entry>
            </row>

            <row>
              <entry><emphasis>\<replaceable>n</replaceable></emphasis></entry>

              <entry>sostituisce tale simbolo con
                l'<replaceable>n-esima</replaceable> stringa corrispondente a
                <replaceable>schema_espressione_regolare</replaceable> chiusa
                tra una coppia di '\(','\)'</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>Questi caratteri speciali possono essere messi in escape con il
        carattere backslash (\) per rimuovere il loro significato
        speciale.</para>

      <para><emphasis>Opzioni generali</emphasis></para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="1.5in">

          <tbody>
            <row>
              <entry><option>-e
                  <replaceable>script</replaceable></option></entry>

              <entry>script di editing</entry>
            </row>

            <row>
              <entry><option>-n</option></entry>

              <entry>non stampa l'output di default, ma solamente quelle linee
                specificate dalle funzioni <command>p</command> o
                <command>s///p</command></entry>
            </row>

            <row>
              <entry><option>-f
                  <replaceable>script_file</replaceable></option></entry>

              <entry>prende lo script di editing dal file specificato</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>Alcune valide flag per le funzioni sostitutive sono:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="0.5in">

          <tbody>
            <row>
              <entry><option>d</option></entry>

              <entry>cancella lo schema</entry>
            </row>

            <row>
              <entry><option>g</option></entry>

              <entry>sostituzione globale dello schema</entry>
            </row>

            <row>
              <entry><option>p</option></entry>

              <entry>stampa le linee</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para><emphasis>Esempi:</emphasis></para>

      <para>Questo esempio modifica tutte le accidentali virgole (,) in una
        virgola seguita da uno spazio (, ) quindi crea l'output:</para>

      <screen>&prompt.user; <userinput>cat filey | sed s/,/,\ /g</userinput></screen>

      <para>Il seguente esempio rimuove tutte le accidentali
        <emphasis>Jr</emphasis> precedute da uno spazio
        (<emphasis>Jr</emphasis>) all'interno del file
        <filename>filey</filename>:</para>

      <screen>&prompt.user; <userinput>cat filey | sed s/\ Jr//g</userinput></screen>

      <para>Per realizzare operazioni multiple sull'input, si precede ogni
        operazione con l'opzione <option>-e</option> (edit) e si quota la
        stringa.  Ad esempio, per filtrare le linee contenenti <quote>Date:
        </quote> e <quote>From: </quote> e rimpiazzarle senza i due punti
        (:):</para>

      <screen>&prompt.user; <userinput>sed -e 's/Date: /Date /' -e 's/From: /From /'</userinput></screen>

      <para>Per visualizzare solamente le linee del file che iniziano con
        <quote>Date:</quote> e includerne una che inizia con
        <quote>Name:</quote>:</para>

      <screen>&prompt.user; <userinput>sed -n '/^Date:/,/^Name:/p'</userinput></screen>

      <para>Per stampare solamente le prime 10 linee dell'input (un rimpiazzo di
        &man.head.1;):</para>

      <screen>&prompt.user; <userinput>sed -n 1,10p</userinput></screen>
    </sect2>

    <sect2 id="text-processing-commands-awk-nawk-gawk">
      <title>awk, nawk, gawk</title>

      <para>&man.awk.1; &egrave; un linguaggio di elaborazione e ricerca di
        schemi.  Il suo nome deriva dalle ultime iniziali dei tre autori:
        Alfred. V. Aho, Peter. J.Weinberger e Brian. W. Kernighan.
        <command>nawk</command> &egrave; un <emphasis>nuovo</emphasis>
        &man.awk.1;, una nuova versione del programma e &man.gawk.1; &egrave;
        il <emphasis>gnu</emphasis> &man.awk.1;, da parte della Free Software
        Foundation.  Ogni versione &egrave; leggermente differente.  Qui ci si
        limiter&agrave; ad illustrare semplici esempi che potrebbero andar bene
        per tutte le versioni.  In alcuni sistemi operativi &man.awk.1; &egrave;
        in realt&agrave; <command>nawk</command>.</para>

      <para>&man.awk.1; ricerca schemi nel suo input e realizza le operazioni
        specificate su ogni linea o sui campi di linea che contengono tali
        schemi.  Le espressioni dello schema di confronto per &man.awk.1;
        possono essere specificate sia attraverso linea di comando, sia
        inserendole in un file e usando l'opzione <option>-f
        <replaceable>file_programma</replaceable></option>.</para>

      <para><emphasis>Sintassi</emphasis></para>

      <para><command>awk <replaceable>programma</replaceable>
          [<replaceable>file</replaceable>]</command></para>

      <para>dove <replaceable>programma</replaceable> &egrave; composto da uno o
        pi&ugrave; dei seguenti campi:</para>

      <para><replaceable>schema</replaceable>
        { <replaceable>azione</replaceable> }</para>

      <para>Ogni linea di input viene verificata con lo schema di confronto
        insieme alla specifica azione che bisogna realizzare per ogni
        corrispondenza trovata.  Questo continua attraverso la completa sequenza
        di schemi, quindi la prossima linea di input viene verificata.</para>

      <para>L'<emphasis>input</emphasis> &egrave; diviso tra
        <emphasis>record</emphasis> e <emphasis>campi</emphasis>.  Il separatore
        di <emphasis>record</emphasis> di default &egrave; newline e la
        variabile <literal>NR</literal> tiene il conto dei record.  Il
        separatore di <emphasis>campo</emphasis> di default &egrave; uno spazio
        bianco, <emphasis>spazi</emphasis> e <emphasis>tab</emphasis>, e la
        variabile <literal>NF</literal> tiene il conto dei campi.  I separatori
        di input del campo, <literal>FS</literal> e del record,
        <literal>RS</literal>, possono essere settati in qualsiasi momento per
        farli corrispondere a singoli caratteri specifici.  I separatori di
        output del campo, <literal>OFS</literal> e del record,
        <literal>ORS</literal>, possono essere modificati, se si desidera, con
        singoli caratteri specifici.
        <literal>$<replaceable>n</replaceable></literal>, dove
        <replaceable>n</replaceable> &egrave; un intero, viene usato per
        rappresentare l'<replaceable>n-esimo</replaceable> campo di un record
        di input, mentre <literal>$0</literal> rappresenta l'intero record
        di input.</para>

      <para><literal>BEGIN</literal> e <literal>END</literal> sono speciali
        schemi che vengono verificati rispettivamente all'inizio dell'input,
        prima che il primo campo sia letto e alla fine dell'input, dopo che
        l'ultimo campo &egrave; stato letto.</para>

      <para>La <emphasis>stampa</emphasis> &egrave; permessa attraverso
        l'istruzione <command>print</command> e l'istruzione per la stampa
        formattata <command>printf</command>.</para>

      <para>Gli <emphasis>schemi</emphasis> (pattern) possono essere
        espressioni regolari, espressioni aritmetiche relazionali, espressioni
        di valutazione di stringhe e combinazioni buleane di alcune di queste.
        In quest'ultimo caso gli schemi possono essere combinati con i seguenti
        operatori buleani, usando le parentesi per definire le
        combinazioni:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="0.5in">

          <tbody>
            <row>
              <entry><emphasis>||</emphasis></entry>

              <entry>or</entry>
            </row>

            <row>
              <entry><emphasis>&amp;&amp;</emphasis></entry>

              <entry>and</entry>
            </row>

            <row>
              <entry><emphasis>!</emphasis></entry>

              <entry>not</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>La separazione di schemi con virgole definisce un
        <emphasis>range</emphasis> in cui lo schema &egrave; applicabile,
        esempio:</para>

      <para><command>/<replaceable>primo</replaceable>/,/<replaceable>ultimo</replaceable>/</command></para>

      <para>seleziona tutte le linee partendo con quella che contiene
        <replaceable>primo</replaceable> e continuando inclusivamente fino alla
        linea che contiene <replaceable>ultimo</replaceable>.</para>

      <para>Per selezionare le linee da 15 a 20 si usa il seguente
        schema:</para>

      <para>NR==15 , NR==20</para>

      <para>Le <emphasis>espressioni regolari</emphasis> devono essere chiuse
        tra slashe (/) e i meta-caratteri possono essere messi in escape con il
        carattere di backslash (\).  Le espressioni regolari possono essere
        raggruppate con gli operatori seguenti:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="0.5in">

          <tbody>
            <row>
              <entry><emphasis>|</emphasis></entry>

              <entry>per alternative separate</entry>
            </row>

            <row>
              <entry><emphasis>+</emphasis></entry>

              <entry>una o pi&ugrave;</entry>
            </row>

            <row>
              <entry><emphasis>?</emphasis></entry>

              <entry>zero o una</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>Un confronto di espressione regolare pu&ograve; essere specificato
        con:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="0.5in">

          <tbody>
            <row>
              <entry><emphasis>~</emphasis></entry>

              <entry>contiene l'espressione</entry>
            </row>

            <row>
              <entry><emphasis>!~</emphasis></entry>

              <entry>non contiene l'espressione</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>Quindi il programma:</para>

      <programlisting>$1 ~ /[Ff]rank/</programlisting>

      <para>&egrave; vero se il primo campo, $1, contiene "Frank" o "frank"
        dovunque all'interno del campo.  Per confrontare un campo identico a
        "Frank" o "frank" si usa:</para>

      <programlisting>$1 ~ /^[Ff]rank$/</programlisting>

      <para>Le <emphasis>espressioni relazionali</emphasis> sono permesse usando
        i seguenti operatori relazionali:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="0.5in">

          <tbody>
            <row>
              <entry>&lt;</entry>

              <entry>minore di</entry>
            </row>

            <row>
              <entry>&lt;=</entry>

              <entry>minore o uguale a</entry>
            </row>

            <row>
              <entry>= =</entry>

              <entry>uguale a</entry>
            </row>

            <row>
              <entry>&gt;=</entry>

              <entry>maggiore o uguale a</entry>
            </row>

            <row>
              <entry>!=</entry>

              <entry>non uguale a</entry>
            </row>

            <row>
              <entry>&gt;</entry>

              <entry>maggiore di</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>Non si pu&ograve; conoscere su due piedi se le variabili sono
        stringhe o numeri.  Se nessun operando &egrave; riconosciuto per essere
        un numero, sono realizzati confronti di stringhe.  Altrimenti, viene
        realizzata una comparazione numerica.  In mancanza di informazioni per
        il contrario, viene realizzata una comparazione di stringa, cos&igrave;
        questa:</para>

      <para>$1 &gt; $2</para>

      <para>verr&agrave; valutata con valori di tipo stringa.  Per assicurarsi
        una valutazione numerica, costruire qualcosa simile a:</para>

      <para>( $1 + 0 ) &gt; $2</para>

      <para>Le <emphasis>funzioni matematiche</emphasis> exp, log e sqrt sono di
        tipo built-in.</para>

      <para>Altre funzioni <emphasis>built-in</emphasis> sono:</para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="1.5in">

          <tbody>
            <row>
              <entry><emphasis>index(<replaceable>s</replaceable>,<replaceable>t</replaceable>)</emphasis></entry>

              <entry>ritorna la posizione della stringa
                <replaceable>s</replaceable> dove si presenta il primo
                <replaceable>t</replaceable> o 0 se non esiste</entry>
            </row>

            <row>
              <entry><emphasis>lenght(<replaceable>s</replaceable>)</emphasis></entry>

              <entry>ritorna la lunghezza della stringa
                <replaceable>s</replaceable></entry>
            </row>

            <row>
              <entry><emphasis>substr(<replaceable>s</replaceable>,<replaceable>m</replaceable>,<replaceable>n</replaceable>)</emphasis></entry>

              <entry>ritorna l'<replaceable>n-esimo</replaceable> carattere della
                sottostringa di <replaceable>s</replaceable>, iniziando dalla
                posizione <replaceable>m</replaceable></entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>Gli <emphasis>array</emphasis> sono dichiarati automaticamente
        quando vengono usati, per esempio:</para>

      <para><literal>arr[i]=$1</literal></para>

      <para>assegna il primo campo del corrente record di input all'i-esimo
        elemento dell'array.</para>

      <para>Le espressioni di controllo di flusso <emphasis>if-else</emphasis>,
        <emphasis>while</emphasis> e <emphasis>for</emphasis> sono permesse con
        la sintassi del <emphasis>C</emphasis>:</para>

      <para><command>for (i=1; i &lt;= NF; i++) {azioni}</command></para>

      <para><command>while (i&lt;=NF) {azioni}</command></para>

      <para><command>if (i&lt;NF) {azioni}</command></para>

      <para><emphasis>Opzioni generali</emphasis></para>

      <informaltable frame="none">
        <tgroup cols="2">
          <colspec colwidth="1.5in">

          <tbody>
            <row>
              <entry><option>-f
                  <replaceable>file_programma</replaceable></option></entry>

              <entry>legge i comandi dal file specificato</entry>
            </row>

            <row>
              <entry><option>-F<replaceable>c</replaceable></option></entry>

              <entry>usa il carattere <replaceable>c</replaceable> come il
                carattere di separatore di campo</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para><emphasis>Esempi:</emphasis></para>

      <screen>&prompt.user; <userinput>cat filex | tr a-z A-Z | awk -F: '{printf("7R %-6s %-9s %-24s \n",$1,$2,$3)}' > upload.file</userinput></screen>

      <para>effettua <command>cat</command> su <filename>filex</filename>, che
        &egrave; formattato in questo modo:</para>

      <programlisting>nfb791:99999999:smith
7ax791:999999999:jones
8ab792:99999999:chen
8aa791:999999999:mcnulty</programlisting>

      <para>cambiando tutti i caratteri minuscoli in caratteri maiuscoli con
        l'utility &man.tr.1; e formattando il file come mostrato di seguito, il
        quale viene scritto nel file <filename>upload.file</filename></para>

      <programlisting>7R NFB791 99999999 SMITH
7R 7AX791 999999999 JONES
7R 8AB792 99999999 CHEN
7R 8AA791 999999999 MCNULTY</programlisting>
    </sect2>
  </sect1>
</chapter>

<!--
     Local Variables:
     mode: sgml
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     sgml-parent-document: ("../book.sgml" "book" "chapter")
     End:
-->