English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Comando awk di Linux

Manuale completo dei comandi di Linux

AWK è un linguaggio per la gestione dei file di testo, uno strumento di analisi di testo potente.

Il nome AWK è stato scelto perché prende le iniziali dei cognomi dei tre fondatori Alfred Aho, Peter Weinberger e Brian Kernighan.

Sintassi

awk [opzioni] 'script' var=value file(s)
o
awk [opzioni] -f scriptfile var=value file(s)

Spiegazione delle opzioni:

  • -F fs o --field-separator fs
    Specificare il separatore di campo del file di input, fs è una stringa o un'espressione regolare, come -F:.

  • -v var=value o --asign var=value
    Assegna una variabile definita dall'utente.

  • -f scripfile o --file scriptfile
    Leggi comandi awk da un file di script.

  • -mf nnn e -mr nnn
    Imposta limiti intrinseci per il valore nnn, l'opzione -mf limita il numero massimo di blocchi assegnati a nnn; l'opzione -mr limita il numero massimo di record. Queste funzionalità sono estensioni della versione di awk del Bell Labs, non applicabili all'awk standard.

  • -W compact o --compat, -W traditional o --traditional
    Esegui awk in modalità compatibile. Pertanto, il comportamento di gawk è identico a quello di awk standard, e tutte le estensioni di awk vengono ignorate.

  • -W copyleft o --copyleft, -W copyright o --copyright
    打印简短的版权信息。

  • -W help or --help, -W usage or --usage
    打印全部awk选项和每个选项的简短说明。

  • -W lint or --lint
    打印不能向传统unix平台移植的结构的警告。

  • -W lint-old or --lint-old
    打印关于不能向传统unix平台移植的结构的警告。

  • -W posix
    打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。

  • -W re-interval or --re-inerval
    允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。

  • -W source program-text or --source program-text
    使用program-text作为源代码,可与-f命令混用。

  • -W version or --version
    打印bug报告信息的版本。

基本用法

log.txt文本内容如下:

2 Questo è un test
3 Sei tu come awk
Questo è un test
10 Ci sono arance,mele,mango

用法一:

awk '{[pattern] action}' {filenames}   # 行匹配语句 awk '' 只能用单引号

Esempio:

# 每行按空格或TAB分割,输出文本中的1、4项
 $ awk '{print $1,$4}' log.txt
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # 格式化输出
 $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo

Secondo metodo d'uso:

awk -F # -F è equivalente alla variabile interna FS, specifica il carattere di separazione

Esempio:

# Utilizzare "," come separatore
 $ awk -F, '{print $1,$2}' log.txt
 ---------------------------------------------
 2 Questo è un test
 3 Sei tu come awk
 Questo è un test
 10 Ci sono arance, mele
 # Ogni volta utilizzare variabili interne
 $ awk 'BEGIN{FS=","} {print $1,$2}' log.txt
 ---------------------------------------------
 2 Questo è un test
 3 Sei tu come awk
 Questo è un test
 10 Ci sono arance, mele
 # Utilizzare più separatori. Prima utilizzare lo spazio per dividere, quindi utilizzare "," per dividere ulteriormente i risultati di tale divisione
 $ awk -F '[ ,]' '{print $1,$2,$5}' log.txt
 ---------------------------------------------
 2 questo test
 3 Sono awk
 This's a
 10 There apple

Uso tre:

awk -v # Impostare la variabile

Esempio:

 $ awk -va=1 '{print $1,$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

Uso quattro:

awk -f {script awk} {nomefile}

Esempio:

 $ awk -f cal.awk log.txt

Operatore

OperatoreDescrizione
= += -= *= /= %= ^= **=Assegnazione
?:Espressione condizionale C
||O logico
&&E logico
~ e !~Corrisponde all'espressione regolare e non corrisponde all'espressione regolare
< <= > >= != ==Operatore di confronto
SpazioConnessione
+ -Addizione e sottrazione
* / %Moltiplicazione, divisione e resto
+ - !Unario add, sot e negazione logica
^ ***Elevare a potenza
++ --Aumentare o ridurre, come prefisso o suffisso
$Riferimento al campo
inElementi dell'array

Filtrare le righe dove la prima colonna è maggiore di 2

$ awk '$1>2' log.txt # Comando
Output
3 Sei tu come awk
Questo è un test
10 Ci sono arance,mele,mango

Filtrare le righe dove la prima colonna è uguale a 2

$ awk '$1==2 {print $1,$3}' log.txt # Comando
Output
2 È

Filtrare le righe dove la prima colonna è maggiore di 2 e la seconda colonna è uguale a 'Sono'

$ awk '$1>2 && $2=="Sono" {print $1,$2,$3}' log.txt # Comando
Output
3 Sono

Variabile interna

VariabileDescrizione
$nIl campo n-esimo della registrazione corrente, separati da FS
$0Registrazione di input completa
ARGCNumero di parametri della riga di comando
ARGINDPosizione del file corrente nella riga di comando (iniziando da 0)
ARGVArray dei parametri della riga di comando
CONVFMTFormato di conversione numerica (predefinito %.6g) Array associato alla variabile d'ambiente ENVIRON
ERRNODescrizione dell'ultimo errore di sistema
FIELDWIDTHSElenco delle larghezze dei campi (separati da spazi)
FILENAMEIl nome del file corrente
FNRIl numero di righe contati per ciascun file
FSIl separatore di campo (predefinito è qualsiasi spazio)
IGNORECASESe vero, ignora la differenza tra maiuscole e minuscole durante la corrispondenza
NFIl numero di campi di una riga
NRIl numero di record letti, ossia il numero di riga, inizia da 1
OFMTIl formato di output dei numeri (predefinito è %.6g)
OFSIl separatore di campo di output, predefinito è lo stesso del separatore di campo di input.
ORSIl separatore di record di output (predefinito è un carattere di newline)
RLENGTHLa lunghezza della stringa corrispondente trovata dalla funzione match
RSIl separatore di record (predefinito è un carattere di newline)
RSTARTLa prima posizione della stringa corrispondente trovata dalla funzione match
SUBSEPIl separatore dell'indice dell'array (predefinito è /034)
$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}' log.txt
FILENAME ARGC FNR FS NF NR OFS ORS RS
---------------------------------------------
log.txt 2 1 5 1
log.txt 2 2 5 2
log.txt 2 3 3 3
log.txt 2 4 4 4
$ awk -F' ' BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}' log.txt
FILENAME ARGC FNR FS NF NR OFS ORS RS
---------------------------------------------
log.txt       2       1       '       1       1
log.txt       2       2       '       1       2
log.txt       2       3       '       2       3
log.txt       2       4       '       1       4
# Output del numero di sequenza NR, numero di riga di testo corrispondente
$ awk '{print NR,FNR,$1,$2,$3}' log.txt
---------------------------------------------
1 1 2 Questo è
2 2 3 Sei tu
3 3 Questo è un test
4 4 10 Ci sono
# Specifica il simbolo di separazione di output
$ awk '{print $1,$2,$5}' OFS="$" log.txt
---------------------------------------------
2 $ Questo $ test
3 $ Sei $ awk
Questo's $ a $
10 $ There $

Uso di espressioni regolari, confronto di stringhe

# Output della seconda colonna contenente "th", e stampa la seconda e la quarta colonna
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a

~ indica l'inizio del modello. // contiene il modello.

# Output delle righe contenenti "re"
$ awk '/re/' log.txt
---------------------------------------------
3 Sei tu come awk
10 Ci sono arance,mele,mango

Ignora la maiuscola e la minuscola

$ awk 'BEGIN{IGNORECASE=1} /this/}' log.txt
---------------------------------------------
2 Questo è un test
Questo è un test

Inversione del modello

$ awk '$2 !~ /th/ {print $2,$4}' log.txt
---------------------------------------------
Sono come
a
There orange,apple,mongo
$ awk '/!/th/ {print $2,$4}' log.txt
---------------------------------------------
Sono come
a
There orange,apple,mongo

script awk

Riguardo allo script awk, dobbiamo prestare attenzione a due parole chiave: BEGIN e END.

  • BEGIN{ Qui ci sono le istruzioni da eseguire prima dell'esecuzione }

  • END {Qui ci sono le istruzioni da eseguire dopo aver trattato tutte le righe }

  • {Qui ci sono le istruzioni da eseguire per ogni riga}

Supponiamo di avere un file del genere (tabella dei punteggi degli studenti):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

Ecco il nostro script awk:

$ cat cal.awk
#!/bin/awk -f
#Prima dell'esecuzione
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#In esecuzione
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#Eseguito
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

Vediamo i risultati dell'esecuzione:

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
---------------------------------------------
  TOTALE: 319 393 350
MEDIA: 63.80 78.60 70.00

Altri esempi

Il programma hello world di AWK è:

BEGIN { print "Hello, world!" }

Calcolo della dimensione del file

$ ls -l *.txt | awk '{sum+=$5} END {print sum}'
--------------------------------------------------
666581

Trova le righe di lunghezza maggiore di 80 nel file:

awk 'length>80' log.txt

Stampa della tabella del moltiplicatore 9x9

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

Manuale completo dei comandi di Linux