Linux-awk-Befehl
awk ist eine Sprache zur Verarbeitung von Textdateien und ein leistungsstarkes Werkzeug zur Textanalyse.
awk liest Textdateien Zeile für Zeile und bietet programmiersprachenähnliche Funktionen, wie zum Beispiel:
- Variablendefinition und -berechnung
- Bedingte Anweisungen und Schleifen
- Zeichenkettenverarbeitung und formatierte Ausgabe
Diese Funktionen machen AWK sehr effizient bei der Verarbeitung strukturierter Texte (wie CSV- und Logdateien).
Es heißt awk, weil es die ersten Buchstaben der Nachnamen seiner drei Gründer verwendet: Alfred Aho, Peter Weinberger und Brian Kernighan.
Syntax
awk options 'pattern {action}' file
Optionsparameter-Beschreibung:
options: sind einige Optionen, die zur Steuerung vonawkVerhalten.pattern: ist ein Muster, das zum Abgleichen von Eingabedaten verwendet wird. Wenn es weggelassen wird, dannawkwird es auf allen Zeilen ausgeführt.{action}: ist die Aktion, die auf Zeilen ausgeführt wird, die dem Muster entsprechen. Wenn sie weggelassen wird, ist die Standardaktion, die gesamte Zeile auszugeben.
Beschreibung der Optionsparameter:
-F <分隔符>oder--field-separator=<分隔符>: Gibt das Trennzeichen für Eingabefelder an, Standard ist ein Leerzeichen. Verwenden Sie diese Option, um ein vom Standard abweichendes Feldtrennzeichen anzugeben.-v <变量名>=<值>: Festlegenawkinterne Variablenwerte. Diese Option kann verwendet werden, um externe Werte anawkVariablen im Skript zu übergeben.-f <脚本文件>: Geben Sie eine Datei an, die einawkSkript enthält. Dies ermöglicht es Ihnen, größere Skripte in einer Datei zu schreiben.awkSkript und verwenden Sie dann die-fOption, um es zu laden.-Voder--version: AnzeigenawkVersionsinformationen.-hoder--help: AnzeigenawkHilfeinformationen, einschließlich Optionen und Anwendungsbeispielen.
Im Folgenden finden Sie einige gängige Verwendungsweisen des awk-Befehls:
Die gesamte Zeile ausgeben:
awk '{print}' fileEine bestimmte Spalte ausgeben:
awk '{print $1, $2}' file
Spalten mit einem Trennzeichen angeben:
awk -F',' '{print $1, $2}' file
Die Anzahl der Zeilen ausgeben:
awk '{print NR, $0}' file
Zeilen ausgeben, die eine Zeilennummernbedingung erfüllen:
awk '/pattern/ {print NR, $0}' file
Die Summe einer Spalte berechnen:
awk '{sum += $1} END {print sum}' file
Geben Sie den Maximalwert aus:
awk 'max < $1 {max = $1} END {print max}' fileFormatierte Ausgabe:
awk '{printf "%-10s %-10s\n", $1, $2}' file
Grundlegende Verwendung
Der Inhalt von log.txt ist wie folgt:
2 this is a test 3 Do you like awk This's a test 10 There are orange,apple,mongo
Verwendung 1: Grundlegende Syntax
awk '{ [pattern] action }' filenames
Hinweis:Der awk-Skriptteil muss mit einfachen Anführungszeichen umschlossen werden' ', um ihn einzuschließen.
Beispiel 1: Die 1. und 4. Spalten jeder Zeile ausgeben
awk '{print $1, $4}' log.txt
Ausgabe:
2 a 3 like This's 10 orange,apple,mongo
Beispiel 2: Formatierte Ausgabe
printf kann das Ausgabeformat anpassen (ähnlich wie printf in der Sprache C):
awk '{printf "%-8s %-10s\n", $1, $4}' log.txt
Ausgabe:
2 a 3 like This's 10 orange,apple,mongo
Verwendung 2: Trennzeichen -F angeben
-FDie Option wird verwendet, um das Trennzeichen zwischen Spalten anzugeben, äquivalent zur integrierten VariableFS (Feldtrenner)。
Beispiel 1: Komma,als Trennzeichen verwenden
awk -F, '{print $1, $2}' log.txt
Ausgabe:
2 this is a test 3 Do you like awk This's a test 10 There are orange apple
Beispiel 2: Die integrierte Variable FS verwenden, um das Trennzeichen festzulegen
awk 'BEGIN { FS="," } {print $1, $2}' log.txt
Das Ausgabeergebnis ist dasselbe:
2 this is a test 3 Do you like awk This's a test 10 There are orange apple
Beispiel 3: Mehrere Trennzeichen verwenden (Leerzeichen oder Komma)
[ ,]Bedeutet, dass sowohl Leerzeichen als auch Kommas als Trennzeichen verwendet werden.
awk -F '[ ,]' '{print $1, $2, $5}' log.txt
Ausgabe:
2 this test 3 Do awk This's a 10 There apple
Verwendung 3: -v zum Festlegen von Variablen verwenden
-vDie Option wird verwendet, um externe Variablen vor der Ausführung des AWK-Skripts zu übergeben, häufig für dynamische Zuweisung verwendet.
Syntaxformat:
awk -v 变量名=值 '{动作}' 文件名
Beispiel 1: Eine numerische Variable definieren und sie in der Arithmetik verwenden
awk -va=1 '{print $1, $1+a}' log.txt
Ausgabe:
2 3 3 4 This's 1 10 11
Erklärung:
- -v a=1 bedeutet, die Variable a=1 zu definieren;
- $1+a bedeutet die erste Spalte plus die Variable a.
Wenn $1 keine Zahl ist (wie This's), ist das Ergebnis leer oder wird unverändert ausgegeben.
Beispiel 2: Mehrere Variablen gleichzeitig definieren
awk -va=1 -vb=s '{print $1, $1+a, $1b}' log.txt
Ausgabe:
2 3 2s 3 4 3s This's 1 This'ss 10 11 10s
Erklärung:
- -vb=s definiert eine Zeichenkettenvariable b;
- $1b bedeutet, die erste Spalte und die Variable b zu verketten (z. B. 2s, 10s).
Verwendung 4: -f zum Aufrufen eines externen AWK-Skripts verwenden
Wenn das AWK-Skript lang ist, können Sie die Logik in eine separate Datei schreiben und sie über den Parameter -f laden.
Syntaxformat:
awk -f 脚本文件 文件名
Angenommen, wir haben eine Skriptdatei cal.awk mit folgendem Inhalt:
{ print $1, $1 + 10 }
Führen Sie den Befehl aus:
awk -f cal.awk log.txt
Ausgabe:
2 12 3 13 This's 10 10 20
Erklärung:
- -f cal.awk bedeutet, das externe Skript cal.awk auszuführen;
- AWK führt die im Skript definierten Aktionen für jede Zeile von log.txt aus.
Operatoren
| Operator | Beschreibung |
|---|---|
| = += -= *= /= %= ^= **= | Zuweisung |
| ?: | C-Bedingungsausdruck |
| || | Logisches OR |
| && | Logisches AND |
| ~ und !~ | Übereinstimmung mit regulärem Ausdruck und keine Übereinstimmung mit regulärem Ausdruck |
| < <= > >= != == | Vergleichsoperatoren |
| Speicher | Verkettung |
| + - | Addition, Subtraktion |
| * / % | Multiplikation, Division und Rest |
| + - ! | Unäres Plus, Minus und logische Negation |
| ^ *** | Potenzierung |
| ++ -- | Inkrement oder Dekrement, als Präfix oder Suffix |
| $ | Feldreferenz |
| in | Array-Element |
Zeilen filtern, bei denen die erste Spalte größer als 2 ist
$ awk '$1>2' log.txt #命令 #输出 3 Do you like awk This's a test 10 There are orange,apple,mongo
Zeilen filtern, bei denen die erste Spalte gleich 2 ist
$ awk '$1==2 {print $1,$3}' log.txt #命令
#输出
2 is
Zeilen filtern, bei denen die erste Spalte größer als 2 ist und die zweite Spalte gleich 'Are' ist
$ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt #命令
#输出
3 Are you
Eingebaute Variablen
| Variable | Beschreibung |
|---|---|
| $n | Das n-te Feld des aktuellen Datensatzes, Felder getrennt durch FS |
| $0 | Der vollständige Eingabedatensatz |
| ARGC | Die Anzahl der Kommandozeilenargumente |
| ARGIND | Die Position der aktuellen Datei in der Befehlszeile (beginnend bei 0) |
| ARGV | Array mit Befehlszeilenargumenten |
| CONVFMT | Numerisches Konvertierungsformat (Standard %.6g) ENVIRON assoziatives Array von Umgebungsvariablen |
| ERRNO | Beschreibung des letzten Systemfehlers |
| FIELDWIDTHS | Liste der Feldbreiten (durch Leerzeichen getrennt) |
| FILENAME | Aktueller Dateiname |
| FNR | Zeilennummer wird für jede Datei separat gezählt |
| FS | Feldtrennzeichen (Standard ist ein beliebiges Leerzeichen) |
| IGNORECASE | Wenn true, wird eine Suche ohne Berücksichtigung der Groß-/Kleinschreibung durchgeführt |
| NF | Die Anzahl der Felder in einem Datensatz |
| NR | Die Anzahl der bereits gelesenen Datensätze, d. h. die Zeilennummer, beginnend bei 1 |
| OFMT | Ausgabeformat für Zahlen (Standard %.6g) |
| OFS | Ausgabe-Feldtrennzeichen; der Standardwert entspricht dem Eingabe-Feldtrennzeichen. |
| ORS | Ausgabedatensatz-Trennzeichen (Standard ist ein Zeilenumbruch) |
| RLENGTH | Die Länge der Zeichenkette, die von der match-Funktion gefunden wurde |
| RS | Datensatz-Trennzeichen (Standard ist ein Zeilenumbruch) |
| RSTART | Die erste Position der Zeichenkette, die von der match-Funktion gefunden wurde |
| SUBSEP | Array-Index-Trennzeichen (Standard ist /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
# 输出顺序号 NR, 匹配文本行号
$ awk '{print NR,FNR,$1,$2,$3}' log.txt
---------------------------------------------
1 1 2 this is
2 2 3 Are you
3 3 This's a test
4 4 10 There are
# 指定输出分割符
$ awk '{print $1,$2,$5}' OFS=" $ " log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a $
10 $ There $
Verwendung regulärer Ausdrücke, Zeichenkettenabgleich
# 输出第二列包含 "th",并打印第二列与第四列
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a
~ kennzeichnet den Beginn eines Musters. // enthält das Muster.
# 输出包含 "re" 的行 $ awk '/re/ ' log.txt --------------------------------------------- 3 Do you like awk 10 There are orange,apple,mongo
Groß-/Kleinschreibung ignorieren
$ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
---------------------------------------------
2 this is a test
This's a test
Musternegation
$ awk '$2 !~ /th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
$ awk '!/th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
awk-Skript
Bei awk-Skripten müssen wir auf zwei Schlüsselwörter achten: BEGIN und END.
- BEGIN{ Hier werden die Anweisungen platziert, die vor der Verarbeitung ausgeführt werden }
- END { Hier werden die Anweisungen platziert, die nach der Verarbeitung aller Zeilen ausgeführt werden }
- { Hier werden die Anweisungen platziert, die bei der Verarbeitung jeder Zeile ausgeführt werden }
Angenommen, es gibt eine solche Datei (Notenliste der Schüler):
$ 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
Unser awk-Skript sieht wie folgt aus:
$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf "---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
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
}
Werfen wir einen Blick auf das Ausführungsergebnis:
$ 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 --------------------------------------------- TOTAL: 319 393 350 AVERAGE: 63.80 78.60 70.00
Noch einige Beispiele
Das AWK-Hallo-Welt-Programm ist:
BEGIN { print "Hello, world!" }
Dateigröße berechnen
$ ls -l *.txt | awk '{sum+=$5} END {print sum}'
--------------------------------------------------
666581
Finde Zeilen, die länger als 80 Zeichen in einer Datei sind:
awk 'length>80' log.txt
Die 9x9-Multiplikationstabelle ausgeben
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")}'
Andere ErweiterungenWeitere Inhalte:
Linux-Befehlsreferenz