awk Tutorial
Iniziare con awk
Ricerca…
Osservazioni
Il nome AWK deriva dalle ultime iniziali dei suoi creatori Alfred V. Aho, Peter J. Weinberger e
Brian W. Kernighan.
risorse
Versioni
| Nome | Versione iniziale | Versione | Data di rilascio |
|---|---|---|---|
| POSIX awk | 1992 | IEEE Std 1003.1, edizione 2013 | 2013/04/19 |
| Un awk vero awk o nawk o BWK | 198X | - | 2012/12/20 |
| GNU awk o gawk | 1986 | 4.1.3 | 2015/05/19 |
Ciao mondo
L'esempio Hello world è semplice come:
awk 'BEGIN {print "Hello world"}'
Il programma awk più basilare consiste in un valore vero (tipicamente 1 ) e fa awk echo il suo input:
$ date | awk '1'
Mon Jul 25 11:12:05 CEST 2016
Dal momento che "Hello World" è anche un vero valore, potresti anche dire:
$ date | awk '"hello world"'
Mon Jul 25 11:12:05 CEST 2016
Tuttavia, la tua intenzione diventa molto più chiara se scrivi
$ date | awk '{print}'
Mon Jul 25 11:12:05 CEST 2016
anziché.
Come eseguire i programmi AWK
Se il programma è breve, puoi includerlo nel comando che esegue awk:
awk -F: '{print $1, $2}' /etc/passwd
In questo esempio, utilizzando l'opzione della riga di comando -F: ti consigliamo di usare awk: come delimitatore dei campi di input. È lo stesso come
awk 'BEGIN{FS=":"}{print $1,$2}' file
In alternativa, possiamo salvare l'intero codice awk in un file awk e chiamare questo programma awk in questo modo:
awk -f 'program.awk' input-file1 input-file2 ...
program.awk può essere qualsiasi programma multilinea, ovvero:
# file print_fields.awk
BEGIN {print "this is a header"; FS=":"}
{print $1, $2}
END {print "that was it"}
E poi eseguirlo con:
awk -f print_fields.awk /etc/passwd #-f advises awk which program file to load
O più in generale:
awk -f program-file input-file1 input-file2 ...
Il vantaggio di avere il programma in un file separato è che puoi scrivere il programma con l'identificazione corretta per avere un senso, puoi includere commenti con #, ecc.
AWK con esempi
AWK è un linguaggio di manipolazione delle stringhe, utilizzato in gran parte nei sistemi UNIX. L'idea alla base di AWK era di creare un linguaggio versatile da utilizzare quando si lavorava sui file, che non era troppo complesso da comprendere.
AWK ha alcune altre varianti, ma il concetto principale è lo stesso, solo con funzionalità aggiuntive. Queste altre varianti sono NAWK e GAWK. GAWK contiene tutte le funzionalità di entrambi, mentre NAWK è un gradino sopra AWK, se lo desideri.
Il modo più semplice per pensare a AWK è considerare che ha 2 parti principali. Il modello e l'azione.
Probabilmente l'esempio più semplice di AWK: (Vedi anche: Hello World)
BEGIN {print "START"}
{print }
END {print "STOP" }
Qui, le parole chiave BEGIN e END sono il modello, mentre l'azione è all'interno di {}. Questo esempio sarebbe inutile, ma richiederebbe solo piccole modifiche per renderlo veramente utile.
BEGIN {print "File\tAuthor"}
{print $8, "\t", $3}
END {print " - DONE - "}
Qui, \t rappresenta un carattere di tabulazione e viene utilizzato per aumentare i limiti della linea di output. $ 8 e $ 3 sono simili all'uso che si vede in Shell Scripts , ma invece di usare il 3 ° e l'8 ° argomento, usa la 3a e l'8a colonna della riga di input.
Quindi, questo esempio dovrebbe stampare: File Autore nella riga superiore, mentre la seconda riga ha a che fare con i percorsi dei file. $ 8 è il nome del file, $ 3 è il proprietario (quando si guarda il percorso della directory, questo sarà più chiaro). Infine, la linea di fondo verrebbe stampata, come ci si aspetterebbe - FATTO -
Il credito per l'esempio precedente va a http://www.grymoire.com/Unix/Awk.html
File di riferimento
coins.txt di Greg Goebel:
gold 1 1986 USA American Eagle
gold 1 1908 Austria-Hungary Franz Josef 100 Korona
silver 10 1981 USA ingot
gold 1 1984 Switzerland ingot
gold 1 1979 RSA Krugerrand
gold 0.5 1981 RSA Krugerrand
gold 0.1 1986 PRC Panda
silver 1 1986 USA Liberty dollar
gold 0.25 1986 USA Liberty 5-dollar piece
silver 0.5 1986 USA Liberty 50-cent piece
silver 1 1987 USA Constitution dollar
gold 0.25 1987 USA Constitution 5-dollar piece
gold 1 1988 Canada Maple Leaf
Teoria minimale
Generalità awk one-liner:
awk <awk program> <file>
o:
<shell-command> | awk <awk program>
<shell-command> e <file> sono indirizzati come input awk .
<awk program> è un codice che segue questo modello (singolo, non doppio, virgolette):
'BEGIN {<init actions>};
<cond1> {<program actions>};
<cond2> {<program actions>};
...
END {<final actions>}'
dove:
-
<condX>condizione<condX>è molto spesso un'espressione regolare/re/, da abbinare alle linee di input di awk; -
<* actions>sono sequenze di istruzioni , simili ai comandi della shell, dotate di costrutti simili a C.
`` viene elaborato secondo le seguenti regole:
-
BEGIN ...edEND ...sono opzionali ed eseguiti prima o dopo l'elaborazione delle righe di input di awk. - Per ogni riga nell'input awk, se la condizione
<condN>è meat, viene eseguito il relativo blocco<program actions>. -
{<program actions>}impostazione predefinita{print $0}.
Le condizioni possono essere combinate con operatori logici standard:
/gold/ || /USA/ && !/1986/
dove && ha la precedenza su || ;
La dichiarazione di print print item1 item2 statement stampa gli articoli su STDOUT.
Gli elementi possono essere variabili ( X , $0 ), stringhe ("ciao") o numeri.
item1, item2 vengono confrontati con il valore della variabile OFS ;
item1 item2 sono justapoxed ! Usa item1 " " item2 per spazi o printf per più funzioni.
Le variabili non hanno bisogno di $ , cioè: print myVar;
Le seguenti variabili speciali sono integrate in awk:
-
FS: funge da separatore di campo per dividere le linee di input di awk nei campi. Posso essere un singolo personaggio,FS="c"; una stringa nulla,FS=""(quindi ogni singolo carattere diventa un campo separato); un'espressione regolare senza barre,FS="re";FS=" "sta per le corse di spazi e tab e il valore di default. -
NF: il numero di campi da leggere; -
$1,$2, ...: 1 ° campo, 2 ° campo. ecc. della linea di ingresso corrente, -
$0: linea di input corrente; -
NR: numero della linea attuale. -
OFS: stringa per fascicolare i campi quando stampati. -
ORS: separatore dei record di output, per impostazione predefinita una nuova riga. -
RS: Separatore della riga di input (registrazione). Il valore predefinito è newline. Imposta comeFS. -
IGNORECASE: influisce su FS e RS quando sono espressione regolare;
Esempi
Filtra le linee con regexp gold e contale:
# awk 'BEGIN {print "Coins"} /gold/{i++; print $0} END {print i " lines out of " NR}' coins.txt
Coins
gold 1 1986 USA American Eagle
gold 1 1908 Austria-Hungary Franz Josef 100 Korona
gold 1 1984 Switzerland ingot
gold 1 1979 RSA Krugerrand
gold 0.5 1981 RSA Krugerrand
gold 0.1 1986 PRC Panda
gold 0.25 1986 USA Liberty 5-dollar piece
gold 0.25 1987 USA Constitution 5-dollar piece
gold 1 1988 Canada Maple Leaf
9 lines out of 13
Default print $0 azione e condizione basata sulla variabile di awk interna NR :
# awk 'BEGIN {print "First 3 coins"} NR<4' coins.txt
First 3 coins
gold 1 1986 USA American Eagle
gold 1 1908 Austria-Hungary Franz Josef 100 Korona
silver 10 1981 USA ingot
Formattazione con `printf` in stile C: # awk '{printf ("%s \t %3.2f\n", $1, $2)}' coins.txt
gold 1.00
gold 1.00
silver 10.00
gold 1.00
gold 1.00
gold 0.50
gold 0.10
silver 1.00
gold 0.25
silver 0.50
silver 1.00
gold 0.25
gold 1.00
Esempi di condizioni
awk 'NR % 6' # prints all lines except those divisible by 6
awk 'NR > 5' # prints from line 6 onwards (like tail -n +6, or sed '1,5d')
awk '$2 == "foo"' # prints lines where the second field is "foo"
awk '$2 ~ /re/' # prints lines where the 2nd field mateches the regex /re/
awk 'NF >= 6' # prints lines with 6 or more fields
awk '/foo/ && !/bar/' # prints lines that match /foo/ but not /bar/
awk '/foo/ || /bar/' # prints lines that match /foo/ or /bar/ (like grep -e 'foo' -e 'bar')
awk '/foo/,/bar/' # prints from line matching /foo/ to line matching /bar/, inclusive
awk 'NF' # prints only nonempty lines (or: removes empty lines, where NF==0)
awk 'NF--' # removes last field and prints the line
Aggiungendo un'azione {...} si può stampare un campo specifico, piuttosto che l'intera linea, ad esempio:
awk '$2 ~ /re/{print $3 " " $4}'
stampa il terzo e il quarto campo di linee in cui il secondo campo inserisce la regex / re /.
Alcune funzioni di stringa
substr() :
# awk '{print substr($3,3) " " substr($4,1,3)}'
86 USA
08 Aus
81 USA
84 Swi
79 RSA
81 RSA
86 PRC
86 USA
86 USA
86 USA
87 USA
87 USA
88 Can
match(s, r [, arr]) restituisce la posizione in s cui si verifica la regex r e imposta i valori di RSTART e RLENGTH . Se viene fornito l'argomento arr , restituisce l'array arr cui gli elementi sono impostati sulla sottoespressione parentesi associata. Le partite dell'elemento 0 di arr sono impostate sull'intera corrispondenza delle espressioni regolari. Anche le espressioni arr[n, "start"] e arr[n, "length"] forniscono la posizione iniziale e la lunghezza di ciascuna sottostringa corrispondente.
Altre funzioni per le stringhe:
sub(/regexp/, "newstring"[, target])
gsub(/regexp/, "newstring"[, target])
toupper("string")
tolower("string")
dichiarazioni
Una semplice affermazione è spesso una delle seguenti:
variable = expression
print [ expression-list ]
printf format [ , expression-list ]
next # skip remaining patterns on this input line
exit # skip the rest of the input
Se stat1 e stat2 sono dichiarazioni, le seguenti sono anche istruzioni:
{stat}
{stat1; stat2}
{stat1
stat2}
if ( conditional ) statement [ else statement ]
I seguenti costrutti C-like standard sono dichiarazioni:
if ( conditional ) statement [ else statement ]
while ( conditional ) statement
for ( expression ; conditional ; expression ) statement
break # usual C meaning
continue # usual C meaning
Un ciclo in stile C per stampare l'elemento di descrizione della lunghezza variabile, iniziando dal campo 4:
# awk '{out=""; for(i=4;i<=NF;i++){out=out" "$i}; print out}' coins.txt
USA American Eagle
Austria-Hungary Franz Josef 100 Korona
USA ingot
Switzerland ingot
RSA Krugerrand
RSA Krugerrand
PRC Panda
USA Liberty dollar
USA Liberty 5-dollar piece
USA Liberty 50-cent piece
USA Constitution dollar
USA Constitution 5-dollar piece
Canada Maple Leaf
Si noti che i è inizializzato a 0.
Se le condizioni e i calcoli sono applicati ai campi nuneric:
# awk '/gold/ {if($3<1980) print $0 "$" 425*$2}' coins.txt
gold 1 1908 Austria-Hungary Franz Josef 100 Korona $425
gold 1 1979 RSA Krugerrand $425
Script eseguibile AWK
#!/usr/bin/gawk -f
# This is a comment
(pattern) {action}
...
Passando le variabili della shell
# var="hello"
# awk -v x="$var" 'BEGIN {print x}'
hello