Stern inaktivStern inaktivStern inaktivStern inaktivStern inaktiv
 

In der c't 22/2014 22/2014 fand sich heute ein sehr schönen Artikel mit demselben Titel. Dort wird anhand von Beispielen erklärt, wie man sehr leicht wegen der Unix Philosophie ohne zu Programmieren durch Einsatz von diversen Befehlszeilentools in Linux Texte bearbeiten, verarbeiten, trennen und zusammenführen kann. Anwendungsbereiche sind csv Dateien verarbeiten, Log Dateien auswerten oder Worthäufigkeitsanalysen und vieles mehr. Vor Kurzem hatte ich ein Problem mit Textdateien welches ich auch mit den meisten in dem Artikel genannten Tools löste. Aber ich war erstaunt, dass diese Tools noch sehr viel mehr können als ich bislang schon wusste. Es macht also durchaus Sinn sich mal die man Pages der Tools im Detail anzusehen. Die folgende Seite listet noch einmal alle Tools sowie ihre guten und mächtigen Aufrufparameter. Details erhält man durch den Aufruf von man für das jeweilige Tool.

cut

Mit cut kann man Teile aus Zeilen ausschneiden.

cut -c5-

Damit werden die ersten 4 Zeichen in einer Zeile gelöscht. Wichtig ist, dass die Parameter zu -c (Zeichen) und -f (Felder) Bereiche sein können. D.h. das finale - bewirkt, dass ab dem 5ten Zeichen alle folgenden Zeichen in der Ausgabe sein sollen. Ohne - erscheint nur das 5te Zeichen pro Zeile.

cut -f3,4 -d' '

Hiermit werden die Felder 3 und 4 aus der Textdatei extrahiert. Der Parameter -d gibt an, dass Felder durch Leerzeichen getrennt sind. Wenn man den Separator einer csv nimmt kann man damit sehr schnell Elemente aus einer csv Spalte  extrahieren.

sort

Um Zeilen von Dateien zusammenzufügen ist oftmals eine Sortierung notwendig. Das Tool sort erledigt die Aufgabe schnell. Hilfreiche Parameter sind -b um führende Leerzeichen zu ignorieren, -i um nicht druckbare Zeichen zu ignorieren, -u um doppelte Einträge zu eleminieren (geht auch mit dem Tool uniq), -k um das Feld zu definieren, nach dem sortiert werden soll sowie -t um den Feldseparator zu definieren

uniq

Die Behandlung von Duplikaten in sortierten Dateien ist mit deisem Tool möglich. Man kann sich die Häufigkeit ausgeben lassen mit -c. Mit -u bekommt man jede Zeile nur einmal (so wie -u in sort) oder mit -d alle mehrfachen Zeilen.

sort a.dat | uniq -c | sort -n

Damit bekommt man z.B. aus einer Liste mit Wörtern pro Zeile die Häufigkeit der einzelnen Wörter.

paste

Mit paste können Zeilen mehrerer Dateien zusammengefügt werden, d.h. alle n-ten Zeilen von zwei Dateien werden in einer Zeile zusammengebracht.

paste -d'-' a.dat, b.dat

ergibt bei a.dat mit zwei Zeilen mit eins und zwei und b.dat mit A und B

eins-A
zwei-B

join

Mit join können Zeilen zweier Dateien zusammengefügt werden, wobei das Zusammenfügen anhand eines gemeinsamen Elementes, dem Schlüssel, in den Zeilen stattfindet. Dabei müssen die Dateien aber nach ihrem Schlüssel sortiert vorliegen. Dabei hilft das sort Tool.

Enthalten z.B. die Dateien a.dat und b.dat

4711 VW
4712 Ferrari

bzw

4711 Gelb
4712 Rot

dann liefert

join a.dat b.dat

eine Liste, wo der Autotyp und die Farbe anhand des Schlüssels Kennnummer zusammengefügt wurde.

4711 VW Gelb
4712 Ferrari Rot

Besonders hilfreich sind noch -d für andere Feldtrenner, -i um Gross-/Kleinschreibung zu ignorieren, -e um fehlende Felder mit Leerzeichen zu füllen. Wenn die Schlüssel nicht an der ersten Stelle in den Dateien stehen sind die Parameter -1 und -2 notwendig.

grep

Mit grep kann man mit Hilfe von regulären Ausdrücken nach Zeilen in Dateien suchen. Mit dem Parameter -v erhält man genau die Zeieln, die den gesuchten Text nicht enthalten. -i bewirkt gross-/kleinschreibungsunabhängige Suche. Mit -w wird nur nach ganzen Worten gesucht.

grep "4711" a.dat

findet z.B. nur die Zeile mit dem VW

yes

Der Sinn des Tools ist eigentlich immer yes zu lieferen. Es kann aber auch sehr gut eingesetzt werden, um Testdaten zu erzeugen.

yes "Hello world" | head -100

erzeugt z.B. 100 Zeilen mit dem Text Hello world

nl

Normalerweise kann man damit Zeilen mit Zeilennummer versehen. Aber man kann auch beliebige Texte an Zeilenanfängen durch eine kleinen Trick erzeugen.

nl -s "echo " a.dat | cut -c7-

Man Hängt mit dem Parameter -s noch einen Text hinter der Nummer an und löscht die Nummer anschliessend wieder mit cut. Natürlich geht das auch mit awk oder sed.

tr

Möchte man Zeichen in Zeilen löschen oder durch andere Zeichen ersetzen bietet sich tr an. Mit -d werden Zeichen gelöscht. Es gibt auch Zeichenmengen wie [:upper:], [:punct:], [:space:] usw die bestimmte Zeichengruppen zusammenfassen. Das geht natürlich auch mit awk oder sed.

tr -d [:punct:] 

Damit werden alle Zeichensetzungszeichen wie Punkt und Komma gelöscht.

tr '\n' '\r\n'

So kann man eine Datei mit Linux Zeilenende für Windows umwandeln oder umgekehrt (So wie die Tools dos2unix und unix2dos)

tr -s ' '

Hiermit werden mehrere Leerzeichen zu einem Leerzeichen gekürzt.

fold

Umbrechen von Zeilen nach einem bestimmten Zeichen

fmt

Formatiert Zeilen und Absätze intelligenter als fold

fmt -0 a.dat

Der Befehl trennt Text so, dass in jeder Zeile ein Wort steht.

 

Anbei noch ein schöner Einzeiler aus dem c't Artikel, der viele der oben genannten Tools benutzt. Man kann das natürlich auch programmatisch erledigen. Aber warum ein Programm schreiben, wenn einem Unix alle Tools an die Hand liefert, die, geschickt kombiniert, gemeinsam die Aufgabe ebenso schnell erledigen?

fmt -0 artikel.txt | tr -d [:punct:] | grep -w -i -v -f stopwords.txt | sort | uniq -c | sort -n

Mit diesem Befehl extrahiert man aus einer Datei artikel.txt alle Worte, die nicht in einer Stopwortliste enthalten sind und zählt ihr Vorkommen. Wenn man das bei wordle.net eingibt bekommt man eine schöne Wortcloud des Artikels.

Kommentar schreiben

*** Hinweis ***

Kommentare sind erwünscht. Aber um lästige Spamposts abweisen zu können gibt es ein paar Dinge die zu beachten sind:
  1. Kommentare mit dem Text http werden sofort zurückgewiesen mit der Meldung Sie sind nicht berechtigt den Tag zu verwenden. zz
  2. Kommentare werden manuell überprüft und es dauert deshalb in der Regel einen Tag bis sie veröffentlicht werden.