Benutzer-Werkzeuge

Webseiten-Werkzeuge


awk

Konzept

awk ist Zeilenorientiert - alle Anweisungen (außer Begin und End) auf die aktuell eingelesene Zeile angewendet. Anschließend wird die nächste Zeile eingelesen und das gleiche wiederholt.

Jede Zeile (Record) wird in Felder (Fields) zerlegt, auf die über Variablen $1 bis $x zugegriffen werden kann.

Die Zeichen anhand der das Ende eines Rekord (Zeile) erkannt wird kann frei definiert werden, gleiches gilt das Zeichen anhand dessen die einzelnen Fields (Felder) separiert werden - Default: New Line-Character bzw. Space.

  • Zeilenorientiert
    • eine Zeile = ein Record
    • Das Zeichen welches einen Record beendet ist frei definierbar
      • per Default: New Line-Zeichen
  • Auftrennung des Records in Fields (Felder)
    • auf die einzelnen Felder kann über Variablen zugegriffen werden
    • das Zeichen zum Auftrennen in Felder kann frei definiert werden
      • per Default ist es ein Leerzeichen

Aufbau

Syntax:

BEGIN {
             Code;
}


/PATTERN/{
        Code;
}


END{
       Code;
}
  • BEGIN und END sind optional und werden jeweils am Anfang und Ende des gesamten Scriptes ausgeführt
    • diese Funktionen werden also nicht für jede Zeile ausgeführt
    • können beliebige Aktionen/Code enthalten, die nur vor dem Einlesen der ersten Zeile und nach dem alle Zeilen eingelesen wurden, ausgeführt werden


  • alle anderen Funkionen werden immer ausgeführt - für jede Zeile die eingelesen wird
  • die /Pattern/ sind Bedingungen die gegeben sein müssen, damit die Action (der darauffolgende Code Block) ausgeführt wird - so wie if-Anweisungen.
    • Pattern sind optional, Actions ohne Pattern davor werden immer ausgeführt


  • Ein Action-Block kann aus mehreren Aktionen/Befehlen bestehen
    • das einleitende { muss direkt (in der gleichen Zeile) wie das Pattern stehen
    • einzelne Aktionen werden durch „;“ getrennt

Pattern/Bedingungen

Es gibt mehrere Bedingungen bzw. Gestaltungsmöglichkeiten dieser.

BEGIN/END

  • der Code-Block wird am Anfang des Scripts bzw. am Ende der Ausführung des Scripts ausgeführt

BEGINFILE/ENDFILE

  • Der Code-Block wird am Anfang oder Ende einer jeden Eingabedatei ausgeführt
  • Man kann awk mehrere Dateien als Argument übergeben

Regular Expression

Syntax:

/Regular Expression/{
some Code
}


Beispiel:

/192.168.20.[0-9]/{
some Code
}


Beispiel matcht wenn die IP mit 192.168.20 beginnt und auf 0-9 endet.

  • Supported werden extended Regular Expressions (siehe man Page)
  • Regular-Expressions müssen immer innerhalb von / / stehen (auch wenn sie mit anderen Anweisungen kombiniert werden)
  • der Code-Block wird ausgeführt wenn der Regular Expression auf die aktuelle Zeile zutrifft
    • Achtung es reicht wenn der Regular-Expression irgendwo auf der Zeile zutrifft. Es muss nicht die ganze Zeile zutreffen → 192.168.20.[0-9] würde auch matchen wenn die Zeile: „Dies ist die IP-Adresse:

192.168.20.9“ heißt.

Relational Expression

Sind komplexere Bedingungen bei denen gegen Feld-Variablen oder andere Variablen geprüft werden kann.
Mehrere Bedingungen können verknüpft werden.

Syntax:

Variable Vergleichsoperator Ausdruck{
Code
}
<code>
\\ \\

Variablen

Es gibt 3 Arten von Variablen.

Fields

  • enthalten den Inhalt von Feldern
    • werden als $1-$x angesprochen (die Felder sind durchnummeriert)
      • die Benamung ist auch beim Ändern/setzen von Werten so
    • $0 enthält den gesamten Record/Zeile

Built-In

  • Variablen deren Inhalt das Verhalten von awk bestimmen oder die Sjantatusinformationen enthalten
    • haben normale Namen (ohne irgend etwas davor)

Einige Variablen:

Name Beschreibung
FSField Separator - Definiert das/die Trennzeichen bzw. den Regular Expression zum Trennen der Fields/Felder.

Eine Eingabezeile wird an den Stellen wo der Field Seperator in der Zeile gefunden wird in einzelne Felder zerlegt, auf die anschließend per $1-$x zugegriffen werden kann. Der Field Seperator wird dabei entfernt
Eingabestring: Hallo-du-Mensch
awk-Aufruf: awk 'BEGIN{FS="-"}{print $2}'
Ausgabe: du

In obigem Beispiel ist der Field—Seperator (FS=) auf „-“ gesetzt.
Aus dem String „Hallo-du-Mensch“ werden also im awk-Script die Felder „Hallo“ „du“ „Mensch“ - die über $1, $2 und $3 angesprochen werden können.

Der Field-Seperator kann beim Aufruf gesetzt werden über die Option -F:

awk -F "-" '{Code}'

oder in der BEGIN-Funktion:

awk '{BEGIN FS="-"}



Field-Seperator kann ein einzelnes Zeichen, eine Zeichenkette oder ein regular Expression sein (was mehrer Zeichen/Zeichenketten als Feldtrenner ermöglicht).

FS="-"

In diesem Fall ist der Feldtrenner das Zeichen „-“.


FS=");"

In diesem Fall ist die Zeichenkette „);“ der Feldtrenner.
Beispielweise würde:

511);622, 633

in die Felder: „511“ und „622, 633“ zerlegt werden.
Aber:

511;622, 633

würden nicht zerlegt werden.

Es muss immer die gesamte Zeichenkette zu finden sein die als Feldtrenner angegeben wurde.


FS="-[0-9]{1,2}"

In diesem Fall ist der Feldtrenner das Zeichen „-“ + eine Zahl im Bereich 0-9 die mindestens einmal aufauchen muss, maximal 2 mal auftauchen darf - es handelt sich hier um einen regulären Ausdruck.
Das bedeutet:

  • „abc-def“ würde nicht zerlegt, weil „-“ alleine kein gültiger Feldtrenner ist
  • „abc-1def“ würde zerlegt in die Felder „abc“ und „def“ → auf „-1“ passt der reguläre Ausdruck im Feldtrenner
  • „abc-19def“ würde zerlegt in die Felder „abc“ und „def“ → auf „-1“ passt der reguläre Ausdruck im Feldtrenner



-F "-|:"

In diesem Fall ist entweder „-“ oder „:“ der Feldtrenner.
Das bedeutet:

  • „abc:def“ → würde zerlegt in „abc“ und „def“
  • „abc-def“ → würde zerlegt in „abc“ und „def“
  • „abc:-def“ → würde zerlegt in „abc“, „“ und „def“ - das „“ kommt daher, da zwischen dem Feldtrenner „:“ und „-“ keine Zeichen sind, es ensteht ein leeres Feld
RSRecord Separator - Definiert das Trennzeichen bzw. den Regular Expression zum Trennen der Records/Zeilen.

awk ließt einen Zeichenstrom (zum Beispiel eine Datei) sequentiell bis es auf den RS (Record Separator) stößt ein. Wird der RS gefunden, wird alles bisher (bzw. zwischen dem aktuellen RS und dem davor) in der Variable $0 gespeichert, anschließend wird die Zeichenkette anhand des FS in Felder zerlegt und das awk-Script auf den Record/Zeile in $0 angewendet.
Der RS ist bei Default Newline (\n), womit bei default eine Zeile in einem Texteditor einem Record in awk entspricht.

Eingabestring: Dies ist ein Satz. Dies ist der nächste. Dies der danach.
Script: awk 'BEGIN{RS="."} {print $0}'
Ausgabe: 
Dies ist ein Satz
Dies ist der nächste
Dies der danach

In obigem Beispiel enthält $0 den aktuellen Record, da „.“ der Recordseperator ist, landed immer ein Satz in $0, danach wird das awk-Script für den aktuellen Record (in diesem Fall also für je einen Satz) ausgeführt → in diesem Fall die Ausgabe des aktuellen Satzes.

Eingabestring: Dies ist ein Satz. Dies ist der nächste. Dies der danach.
Script: awk 'BEGIN{RS="."} {print $2}'
Ausgabe: 
ist
ist
der

Obiges Beispiel ließt je einen Satz ein (da ein Record jeweils durch „.“ getrennt wird) und gibt das 2 Feld in jedem der eingelesenen Records aus.

Im Prinziep trifft alles (die definierbaren regular Expressions usw.) vom Field Seperator auch auf den Recordseperator zu.

OFSOutput Field Seperator - Definiert das Trennzeichen
ORSOutput Record Seperator - Definiert wie Records bei der Ausgabe getrennt werden.

Per Default durch New Line (\n).

Bei der Ausgabe ist ein Record ein print-Statement und alles was dies ausgibt. Gibt es mehrere Ausgaben durch print, startet jedes print-Statement einen neue Zeile/Record - auch wenn sie das Ergebnis der gleichen Eingabezeile/Eingaberecord sind.
ps axu | awk 'BEGIN{ORS="; "}{print $2, $11; print "zweite ausgabe"}'



Die Ausgabe:

1 /sbin/init; zweite ausgabe; 2 [kthreadd]; zweite ausgabe;



1 und /sbin/init und sind der Inhalt von $1 und $11 des ersten print statements.
„zweite ausgabe“ ist die Ausgabe des zweiten print-Statements.
Da jedes print-Statement einen eigenen Record erzeugt, sind „1 /sbin/init“ und „zweite ausgabe“ durch das ORS-Zeichen getrennt - in diesem Fall durch „;“.

* match-Funktionen ergeben auch true wenn nur ein Teilstring gematcht wird

  • Reguläre Ausdrücke müssen nicht so konstruiert werden das sie den gesamten String erfassen, sondern es reicht wenn sie auf einen zusammenhängenden Teilstring passen
  • FS → Field-Seperator kann nur in BEGIN definiert werden
  • hat keinen Effekt wenn es später deklairert wird
  • Arrays werden ohne voran gestelltes $ angesprochen - sowohl bei Zuweisung, als auch bei lesendem Zugriff
  • { muss direkt nach dem Bereichs-Funktionskopf stehen → darf nicht in der nächsten Zeile stehen

Grundaufbau

Syntax:

BEGIN {
             Code;
}


/PATTERN/{
        Code;
}


END{
       Code;
}
  • Pattern: Regulärer Ausdruck (oder etwas anderes?), Funktionsname → dann ist es eine Funktion die später aufgerufen werden kann, oder gar nichts → dann wird es immer ausgeführt.
awk.txt · Zuletzt geändert: 2017/10/19 21:33 von root