Zuletzt angesehen: » script » torsmo » iso-images_mounten » gimp » openoffice_unter_freebsd » netbook » mounten » neues_wiki » openoffice » awk
AWK
Dies ist eine Ergänzung zu shell-scripting in der es um die Sprache AWK geht.
Es wird eine allgemeine Schnelleinführung geben und ein Sammlung von nützlichen awk-Schnipseln, die awk erläutern und auch so für den täglichen BSD-Einsatz nützlich sind.
AWK-Basics
AWK ist eine Skriptsprache die als einfacher Vorgänger von Perl gilt. AWK zerlegt die Eingabedaten, /dev/stdin oder eine Datei, in so genannte records (normalerweise eine Zeile) und diese records in fields (eine Spalte, normalerweise getrennt von Leerzeichen oder Tabulatoren). Das Skript selbst wird awk entweder als Parameter übergeben oder kann in einer Datei liegen, die mit dem Parameter -f aufgerufen wird.
Diese Eingabedaten können dann mit mehreren Blöcken Code verarbeitet werden. Jedem Block kann optional ein Regulärer Ausdruck vorangestellt werden, mit dem gesteuert wird ob der aktuelle record von dem Block bearbeitet wird oder nicht.
Das folgende Beispiel übergibt das Skript als Parameter. Dem Block ist in / eingeschlossen ein regulärer Ausdruck vorangestellt, der Groß-/Kleinschreibung ignoriert (das i hinter dem abschließenden /).
> dmesg | awk '/intel/i {if ($1 ~ ":$" ) {print $1;}}'
Zusätzlich gibt es die Möglichkeit einen BEGIN-Block und einen END-Block anzulegen. Die Blöcke werden dann unabhängig von den Eingabedaten jeweils vor und nach der Verarbeitung der Eingabedaten aufgerufen.
Alle Variablen in AWK sind global. Jedoch können Funktionen angelegt werden, die mit Werte-Übergabe funktionieren. Diesen Umstand kann man ausnutzen um Wrapper-Funktionen um die Grundfunktionen von AWK zu schreiben, die nicht destruktiv für die übergebenen Parameter sind.
AWK stört sich nicht daran, wenn einer Funktion weniger Parameter als definiert übergeben werden. Deshalb kann man über den Umweg der Funktionsparameter lokale Variable erzeugen.
nützliche Minibeispiele
Alle Pakete auflisten, die von keinem anderen Paket benötigt werden
pkg_info -aQR | awk '$0 ~ ":" { split($1,arr,":"); if (arr[2]=="") print arr[1];}'
Alle installierten Pakete mit Origin auflisten
find /var/db/pkg/ -name "+CONTENTS" | xargs awk '$1=="@comment" && substr($2,1,6)=="ORIGIN" { split(FILENAME,a,"/"); print a[5] ":" substr($2,8) }'
das macht dasselbe wie
pkg_ingo -aQo
(und ist auch nicht wirklich schneller) TODO ergänzen
Duplikate ohne Sortieren entfernen
awk '!($0 in prev) {print $0; prev[$0]}'
Es kann auch nach bestimmten Spalten gefiltert und ein Spaltentrennzeichen angeben werden (im folgenden Beispiel die erste Spalte und das Trennzeichen “:“).
awk -F: '!($1 in prev) {print $0; prev[$1]}'
Nur mehrfach vorkommende Zeilen ausgeben
Der folgende Aufruf gibt nur Zeilen aus, die schon einmal aufgetaucht sind:
awk '$0 in occured; {occured[$0]}'
Der nächste Aufruf gibt mehrfach vorkommende Zeilen genau ein mal aus, egal wie oft sie vorkommen:
awk '$0 in occured && !(occured[$0]) {print $0; occured[$0]=1} {occured[$0]}'
nützliche AWK-Skripte
Dieses Skript rückt XML-Dateien automatisch ein.
#!/usr/bin/awk -f # # Copyright (c) 2010 # Dominic Fandrey <kamikaze@bsdforen.de> # # Do as you please, don't blame me for the results. # # # This script indents XML files. # { # Trim line sub("^[[:space:]]*", ""); # Indent depth depending on whether this is a closing line or not i = 0; if ($0 ~ "^</") i++; # Do indent for (; i < depth; i++) $0 = " " $0; # Print print($0); # Throw away tags that do not count, i.e. tags that start with <?, # self-closing tags, e.g. <tag/>, and comments. gsub("<\\?[^>]*>|<[^>]*/>|<!-[^>]->", ""); # Indent depth for the following lines depth -= gsub("</[^>]*>|/>", ""); depth += gsub("<[^>]*>|<(![^-]|[^!])", ""); }
Verweise
- Die Manpage awk(1).
Sie befinden sich hier: Hauptseite » howto » awk