Il linguaggio di programmazione Awk supporta gli array. Come parte della nostra serie di esempi awk in corso, abbiamo visto variabili definite dall'utente awk e variabili integrate awk. Gli array sono un'estensione di variabili. Gli array sono variabili che contengono più di un valore. Simile alle variabili, anche gli array hanno nomi. In alcuni linguaggi di programmazione, gli array devono essere dichiarati, in modo che la memoria venga allocata per gli array. Inoltre, gli indici di array sono in genere interi, come array[1],array[2] ecc.,
Matrice associativa Awk
Awk supporta solo array associativi. Gli array associativi sono come gli array tradizionali tranne per il fatto che usano le stringhe come indici anziché numeri. Quando si utilizza un array associativo, è possibile simulare un array tradizionale utilizzando una stringa numerica come indice.
Syntax: arrayname[string]=value
Nella sintassi awk sopra:
- nome array è il nome dell'array.
- stringa è l'indice di un array.
- valore è qualsiasi valore assegnato all'elemento dell'array.
Accesso agli elementi dell'array AWK
Se vuoi accedere a un particolare elemento in un array, puoi accedervi attraverso il suo indice — arrayname[index], che ti dà il valore assegnato in quell'indice.
Se desideri accedere a tutti gli elementi dell'array, puoi utilizzare un ciclo per scorrere tutti gli indici di un array come mostrato di seguito.
Syntax: for (var in arrayname) actions
Nella sintassi awk sopra:
- variante è qualsiasi nome di variabile
- in è una parola chiave
- nome array è il nome dell'array.
- azioni sono un elenco di dichiarazioni da eseguire. Se vuoi eseguire più di un'azione, deve essere racchiusa tra parentesi graffe.
Questo ciclo esegue un elenco di azioni per ogni diverso valore utilizzato come indice nell'array con la variabile var impostata su quell'indice.
Rimozione di un elemento dall'array AWK
Se vuoi rimuovere un elemento in un particolare indice di un array, usa l'istruzione awk delete. Dopo aver eliminato un elemento da un array awk, non puoi più ottenere quel valore.
Syntax: delete arrayname[index];
Il comando loop seguente rimuove tutti gli elementi da un array. Non esiste una singola istruzione per rimuovere tutti gli elementi da un array. Devi passare attraverso il ciclo ed eliminare ogni elemento dell'array usando l'istruzione awk delete.
for (var in array) delete array[var]
5 esempi pratici di array Awk
Tutti gli esempi forniti di seguito utilizzano il file Iplogs.txt mostrato di seguito. Questo file di testo di esempio contiene un elenco di indirizzi IP richiesti dal server gateway. Questo file Iplogs.txt di esempio contiene dati nel formato seguente:
[date] [time] [ip-address] [number-of-websites-accessed]
$ cat Iplogs.txt 180607 093423 123.12.23.122 133 180607 121234 125.25.45.221 153 190607 084849 202.178.23.4 44 190607 084859 164.78.22.64 12 200607 012312 202.188.3.2 13 210607 084849 202.178.23.4 34 210607 121435 202.178.23.4 32 210607 132423 202.188.3.2 167
Esempio 1. Elenca tutti gli indirizzi IP univoci e il numero di volte in cui è stato richiesto
$ awk '{ > Ip[$3]++; > } > END{ > for (var in Ip) > print var, "access", Ip[var]," times" > } > ' Iplogs.txt 125.25.45.221 access 1 times 123.12.23.122 access 1 times 164.78.22.64 access 1 times 202.188.3.2 access 2 times 202.178.23.4 access 3 times
Nello script sopra:
- Il terzo campo ($3) è un indirizzo IP. Questo è usato come indice di un array chiamato Ip.
- Per ogni riga, incrementa il valore dell'indice di indirizzo IP corrispondente.
- Infine, nella sezione FINE, tutto l'indice sarà l'elenco di indirizzi IP univoci e i valori corrispondenti saranno il conteggio delle occorrenze.
Esempio 2. Elenca tutti gli indirizzi IP e calcola a quanti siti ha avuto accesso
L'ultimo campo in Iplogs.txt è il numero di siti a cui ogni indirizzo IP ha avuto accesso in una data e ora particolare. Lo script seguente genera il rapporto che contiene un elenco di indirizzi IP e quante volte ha richiesto il gateway e il numero totale di siti a cui ha avuto accesso.
$cat ex2.awk BEGIN { print "IP Address\tAccess Count\tNumber of sites"; } { Ip[$3]++; count[$3]+=$NF; } END{ for (var in Ip) print var,"\t",Ip[var],"\t\t",count[var]; } $ awk -f ex2.awk Iplogs.txt IP Address Access Count Number of sites 125.25.45.221 1 153 123.12.23.122 1 133 164.78.22.64 1 12 202.188.3.2 2 180 202.178.23.4 3 110
Nell'esempio sopra:
- Ha due array. L'indice per entrambi gli array è lo stesso, ovvero l'indirizzo IP (terzo campo).
- Il primo array denominato "Ip" ha un elenco di indirizzi IP univoci e il relativo conteggio delle occorrenze. Il secondo array chiamato "count" ha l'indirizzo IP come indice e il suo valore sarà l'ultimo campo (numero di siti), quindi ogni volta che arriva l'indirizzo IP continua ad aggiungere l'ultimo campo.
- Nella sezione END, esamina tutti gli indirizzi IP e stampa l'indirizzo IP e il conteggio degli accessi dall'array chiamato Ip e il numero di siti dal conteggio dell'array.
Esempio 3. Identifica il giorno massimo di accesso
$ cat ex3.awk { date[$1]++; } END{ for (count in date) { if ( max < date[count] ) { max = date[count]; maxdate = count; } } print "Maximum access is on", maxdate; } $ awk -f ex3.awk Iplogs.txt Maximum access is on 210607
In questo esempio:
- l'array denominato "date" ha la data come indice e il conteggio delle occorrenze come valore dell'array.
- max è una variabile che ha il valore di conteggio e utilizzata per scoprire la data che ha il conteggio massimo.
- maxdate è una variabile che ha la data per la quale il conteggio è massimo.
Esempio 4. Invertire l'ordine delle righe in un file
$ awk '{ a[i++] = $0 } END { for (j=i-1; j>=0;) print a[j--] }' Iplogs.txt 210607 132423 202.188.3.2 167 210607 121435 202.178.23.4 32 210607 084849 202.178.23.4 34 200607 012312 202.188.3.2 13 190607 084859 164.78.22.64 12 190607 084849 202.178.23.4 44 180607 121234 125.25.45.221 153 180607 093423 123.12.23.122 133
In questo esempio,
- Inizia registrando tutte le righe nell'array 'a'.
- Quando il programma ha finito di elaborare tutte le righe, Awk esegue il blocco END { }.
- Il blocco END scorre gli elementi nell'array 'a' e stampa le righe registrate in modo inverso.
Esempio 5. Rimuovere le righe duplicate e non consecutive utilizzando awk
$ cat > temp foo bar foo baz bar $ awk '!($0 in array) { array[$0]; print }' temp foo bar baz
In questo esempio:
- Awk legge ogni riga dal file "temp" e tramite l'operatore "in" controlla se la riga corrente esiste nell'array "a".
- Se non esiste, memorizza e stampa la riga corrente.
Lettura consigliata
Sed e Awk 101 Hacks, di Ramesh Natarajan . Trascorro diverse ore al giorno in ambiente UNIX/Linux a occuparmi di file di testo (dati, configurazione e file di registro). Uso Sed e Awk per tutto il mio lavoro di manipolazione del testo. Sulla base della mia esperienza con Sed e Awk, ho scritto Sed and Awk 101 Hacks eBook che contiene 101 esempi pratici su varie funzionalità avanzate di Sed e Awk che miglioreranno la tua vita UNIX / Linux. Anche se usi Sed e Awk da diversi anni e non hai letto questo libro, per favore fatti un favore e leggi questo libro. Rimarrai stupito dalle capacità delle utility Sed e Awk.