Unbekanntere Linux-Werkzeuge ausprobieren (Teil 1)

Aus LinuxUser 03/2019

Unbekanntere Linux-Werkzeuge ausprobieren (Teil 1)

© Charles Taylor, 123RF

Spielzeugkiste

Die Kommandozeile bietet zahlreiche clevere Werkzeuge, die kaum jemand kennt. Wir stellen die nützlichsten davon vor.

Linux ist eine wahre Wundertüte voller Werkzeuge. Neben den üblichen Verdächtigen, die Sie jeden Tag nutzen, wie beispielsweise cd, ls, mkdir, tar, df, cat oder grep, hält es in versteckten Seitentaschen weitere Spezialwerkzeuge bereit. Die tauchen im Inhaltsverzeichnis eines Linux-Buchs, wenn überhaupt, meist nur unter “Sonstiges” auf.

Wir haben diese versteckten Seitentaschen durchstöbert und stellen Ihnen hier die nützlichsten Helfer vor, die wir darin gefunden haben. Dabei widmen wir jedem Werkzeug einen eigenen Absatz mit Praxisbeispielen. Wir können jedoch nicht alle Schalter der Tools vorstellen; ein zusätzlicher Blick in die jeweilige Manpage lohnt sich daher immer.

Um es Ihnen leichter zu machen, geben wir zu jedem Werkzeug das Softwarepaket für Debian GNU/Linux, Ubuntu und Derivate an, in dem sich das besprochene Werkzeug findet. Das essenzielle Paket coreutils [1] zählt dabei zum Standard-Installationsumfang, die entsprechenden Tools liegen also bereits auf Ihrem System. Die anderen Pakete installieren Sie gegebenenfalls per Apt oder Synaptic über die Paketverwaltung nach. Bei anderen Distributionen heißen die diversen Pakete möglicherweise anders, oder das Werkzeug wurde noch gar nicht paketiert.

Fmt

Fmt aus dem Paket coreutils gehört zur Kategorie der Text-Tools. Seine Aufgabe besteht darin, Absätze neu zu formatieren. Es nimmt dazu einen Text über die Standardeingabe entgegen und formatiert ihn mit einer bestimmten Breite im Flattersatz [2], also mit der von Ihnen genannten Anzahl Zeichen pro Zeile. Dabei überschreibt Fmt die Originaldatei nicht, sondern liefert das Ergebnis auf der Standardausgabe aus.

Bei der Reformatierung erfolgt kein gleichmäßiger Ausgleich der Wortabstände wie bei LaTeX, Fmt reduziert jedoch alle mehrfachen Leerzeichen zwischen den einzelnen Worten sowie zwischen Sätzen. Damit stimmt die Optik der resultierenden Absätze, die dann auch keine “Löcher” mehr aufweisen [3].

Die gewünschte Breite des Texts stellen Sie mit dem Schalter -w (--width) ein, gefolgt von der Anzahl der Zeichen. Ohne diese Angabe geht Fmt von 75 Zeichen pro Zeile aus. Abbildung 1 zeigt das Vorgehen für einen neu formatierten Absatz mit 50 Zeichen pro Zeile.

Abbildung 1: Umformatierung eines Absatzes mit fmt.

Abbildung 1: Umformatierung eines Absatzes mit fmt.

Eine Einrückung der ersten Zeile von Absätzen entfernt Fmt üblicherweise, da es die Leerzeichen als überflüssig interpretiert und wegoptimiert. Mit dem Schalter -c (--crown-margin) lässt sich das Werkzeug jedoch vom Gegenteil überzeugen und behält die bereits bestehende Einrückung der ersten beiden Zeilen bei. Abbildung 2 zeigt die Umformatierung mit Zeileneinzug (Einrückung).

Abbildung 2: Umformatierung eines Absatzes mit Einrückung.

Abbildung 2: Umformatierung eines Absatzes mit Einrückung.

Ohne weitere Angaben im Aufruf bearbeitet Fmt alle Zeilen der Eingabe, es kann aber noch deutlich mehr. So modifiziert es mithilfe des Schalters -p (--prefix) nur solche Zeilen des Texts, die mit einer bestimmten Zeichenkette beginnen.

Das erweist sich beispielsweise für Kommentare in Quellcode als nützlich, die dann sauber umbrechen. Ein entsprechendes Beispiel finden Sie in Listing 1. Als Präfix kommt hier ein einzelnes Hashtag (“#”) zum Einsatz. Im Aufruf auf der Kommandozeile steht es in Anführungszeichen, damit es die Shell nicht als Beginn eines Kommentars interpretiert.

Listing 1

$ cat kommentar
# Kommentar, um was zu demonstrieren. Wir
# wollen hier eigentlich nur zeigen, das da etwas Längeres stehen kann
print ("Hello, world!")
$ fmt -w 50 -p "#" kommentar
# Kommentar, um was zu demonstrieren. wir wollen
# hier eigentlich nur zeigen, das da was
# Längeres stehen kann
print ("Hello, world!")

Fold

Fold aus dem Paket coreutils formatiert Text ganz ähnlich wie Fmt, verwendet als Standardbreite jedoch 80 Zeichen pro Zeile. Zudem bricht es exakt nach der genannten Spalte um, unabhängig davon, ob an dieser Position im Text tatsächlich ein Wortende erreicht ist (Listing 2, erster Aufruf). Damit Fold nur an Wortenden umbricht, rufen Sie es mit dem Schalter -s (--spaces) auf. Der zweite Aufruf in Listing 2 zeigt den kleinen, aber feinen Unterschied.

Listing 2

$ fold -w50 vorspann
Die Kommandozeile bietet zahlreiche clevere Werkze
uge, die kaum jemand kennt. Wir stellen die nützl
ichsten davon vor.
$ fold -sw50 vorspann
Die Kommandozeile bietet zahlreiche clevere
Werkzeuge, die kaum jemand kennt. Wir stellen die
nützlichsten davon vor.

Column

Das Kommando Column aus dem Paket bsdmainutils gibt die Eingabedaten spaltenweise aus. Dazu passt es seine Ausgabe an die Breite des Terminalfensters an und teilt die Werte entsprechend auf. Column ordnet dabei die Inhalte von links nach rechts an: Es füllt also zuerst die linke Spalte auf und erst danach die weiteren Spalten rechts daneben. Eine Sortierung der Eingabedaten nimmt es nicht vor, deren Reihenfolge bleibt also erhalten.

Zur Anordnung der Spalten verwendet Column Tabulatoren. Der erste Aufruf in Listing 3 zeigt das für eine Liste, die Column alphabetisch nach dem Ortsnamen sortiert. Mit dem Schalter -x geht das Werkzeug stattdessen zeilenweise vor (zweiter Aufruf). Hier landet Besancon nicht unter Ansbach, sondern in der Spalte rechts daneben.

Listing 3

$ column adressen
D-91522 Ansbach         D-60000 Frankfurt/Main  CH-1000 Lausanne
F-25000 Besancon        CH-1200 Genf            D-80000 München
ZA-8000 Cape Town       D-20000 Hamburg         D-70173 Stuttgart
$ column -x adressen
D-91522 Ansbach         F-25000 Besancon        ZA-8000 Cape Town
D-60000 Frankfurt/Main  CH-1200 Genf            D-20000 Hamburg
CH-1000 Lausanne        D-80000 München         D-70173 Stuttgart

Enthält die Eingabedatei Leerzeilen, beispielsweise als optische Trennung, ignoriert Column diese normalerweise. Mithilfe des Schalters -e bleiben solche Leerzeilen in der Ausgabe erhalten (Listing 4).

Listing 4

$ cat adressen2
D-91522 Ansbach
F-25000 Besancon
ZA-8000 Cape Town
D-60000 Frankfurt/Main
CH-1200 Genf
D-20000 Hamburg
CH-1000 Lausanne
D-80000 München
D-70173 Stuttgart
$ column -e adressen2
D-91522 Ansbach         CH-1200 Genf            D-80000 München
F-25000 Besancon                                D-70173 Stuttgart
ZA-8000 Cape Town       D-20000 Hamburg
D-60000 Frankfurt/Main  CH-1000 Lausanne

Es gibt aber noch eine weitere Funktionsweise von Column: Mit dem Schalter -t behält es existierende Zeilenumbrüche in den Daten bei. Es formatiert die vorhandenen Zeilen dann tabellenartig, indem es die Anzahl der Leerzeichen zwischen den Wörtern so anpasst, dass diese gleichmäßig untereinanderstehen. Die Breite des Terminals ignoriert Column in diesem Fall.

Dies erweist sich insbesondere dann als hilfreich, wenn Sie die Ausgaben von spaltenorientierten Dateiformaten übersichtlicher gestalten möchten. Als typische Kandidaten kommen etwa die Datei /etc/fstab, Crontab-Dateien oder der oft sehr schlecht lesbare Inhalt von /proc/mounts infrage (Listing 5).

Listing 5

$ column -t /proc/mounts
sysfs  /sys       sysfs     rw,nosuid,nodev,noexec,relatime                              0  0
proc   /proc      proc      rw,nosuid,nodev,noexec,relatime                              0  0
udev   /dev       devtmpfs  rw,nosuid,relatime,size=8058040k,nr_inodes=2014510,mode=755  0  0
devpt  /dev/pts   devpts    rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000        0  0
tmpfs  /run       tmpfs     rw,nosuid,noexec,relatime,size=1614172k,mode=755             0  0
tmpfs  /dev/shm   tmpfs     rw,nosuid,nodev                                              0  0
tmpfs  /run/lock  tmpfs     rw,nosuid,nodev,noexec,relatime,size=5120k                   0  0
[...]

Join

Das Werkzeug Join aus dem Paket coreutils kombiniert Zeilen mehrerer Dateien miteinander, die jeweils über ein identisches Feld am Anfang der Zeile (Präfix) verfügen. Das Präfix muss in beiden Dateien in derselben Reihenfolge auftauchen, Join kann also nur mit bereits sortierten Dateien umgehen.

In Listing 6 handelt es sich beim Präfix um eine Mitgliedsnummer. Hier führt Join also zwei Datensätze zusammen, die den Namen beziehungsweise das Geburtsdatum einer Person enthalten. Bei den Datensätzen kann es sich beispielsweise um Tabellen aus einer Datenbank handeln.

Listing 6

$ cat names
Nummer Name
15672 Anna Fischer
31984 Holger Meier
21564 Werner Baumgarten
15670 Gottfried Scherz
$ cat birthdays
Nummer Geburtstag
15672 12.2.1977
31984 1.10.1980
21564 15.11.1974
15670 5.5.2006
$ join names birthdays
Nummer Name Geburtstag
15672 Anna Fischer 12.2.1977
31984 Holger Meier 1.10.1980
21564 Werner Baumgarten 15.11.1974
15670 Gottfried Scherz 5.5.2006

Haben die Überschriften der ersten Spalte eine abweichende Schreibweise, hilft der Schalter -i (kurz für --ignore-case) weiter. Damit vergleicht Join die Felder unabhängig von der Groß- und Kleinschreibung miteinander. Join übernimmt in die Ausgabe die Schreibweise ähnlicher Felder, die es in der ersten Spalte findet. Weichen die Überschriften der ersten Zeile komplett voneinander ab, geben Sie stattdessen den Schalter --header an. Join betrachtet in diesem Fall die erste Zeile als Kopfzeile und verändert sie nicht.

Verarbeiten Sie Dateien mit Trennzeichen, wie etwa eine CSV-Datei, geben Sie den Schalter -t gefolgt vom entsprechenden Delimiter an. Join zerlegt die Zeilen dann anhand dieser Angabe korrekt in einzelne Felder (Listing 7).

Listing 7

$ join -t, names2 birthdays2
Nummer,Name,Geburtsdatum
15672,Anna Fischer,12.2.1977
31984,Holger Meier,1.10.1980
21564,Werner Baumgarten,15.11.1974
15670,Gottfried Scherz,5.5.2006

Paste

Paste aus dem Paket coreutils ähnelt weitgehend Join: Es klebt ebenfalls Dateien zeilenweise zusammen. In Listing 8 fügen wir einer bestehenden CSV-Datei mit Nummer und Name eine weitere Spalte namens Geburtsdatum hinzu. Das angegebene Trennzeichen -d (--delimiter) sorgt dafür, dass dabei jeweils ein Komma als Spaltentrenner zum Einsatz kommt.

Listing 8

$ cat names3
Nummer,Name
15672,Anna Fischer
31984,Holger Meier
21564,Werner Baumgarten
15670,Gottfried Scherz
$ cat birthdays3
Geburtsdatum
12.2.1977
1.10.1980
15.11.1974
5.5.2006
$ paste -d "," names3 birthdays3
Nummer,Name,Geburtsdatum
15672,Anna Fischer,12.2.1977
31984,Holger Meier,1.10.1980
21564,Werner Baumgarten,15.11.1974
15670,Gottfried Scherz,5.5.2006

Paste kann sogar mit mehreren Trennzeichen im Aufruf umgehen. Es fügt dann das erste angegebene Trennzeichen zwischen der ersten und zweiten Spalte der Ausgabe ein, das zweite Trennzeichen zwischen der zweiten und dritten Spalte und so weiter. In Listing 9 fungieren beispielsweise ein Pipe-Symbol als erstes und ein Komma als zweites Trennzeichen. Im Aufruf schließen Sie die Trennzeichen am besten in einfache oder doppelte Anführungsstriche ein, damit sie die ausführende Shell nicht auswertet.

Listing 9

$ paste -d "|," numbers names birthdays
Nummer|Name,Geburtsdatum
15672|Anna Fischer,12.2.1977
31984|Holger Meier,1.10.1980
21564|Werner Baumgarten,15.11.1974
15670|Gottfried Scherz,5.5.2006

Rev

Das Werkzeug Rev aus dem Paket util-linux liest von der Standardeingabe oder aus einer Datei und gibt den Inhalt jeder Zeile zeichenweise in umgekehrter Reihenfolge wieder aus. Listing 10 zeigt den Einsatz des Tools anhand der Datei mit den Geburtstagen aus Listing 6.

Listing 10

$ rev birthdays
mutadstrubeG remmuN
7791.2.21 27651
0891.01.1 48913
4791.11.51 46512
6002.5.5 07651

Tac

Tac aus dem Paket coreutils ähnelt in der Wirkungsweise Rev, fungiert jedoch als Gegenstück zum bekannteren Werkzeug Cat: Es gibt den Inhalt einer Datei in umgekehrter Reihenfolge aus, also die letzte Zeile zuerst, dann die vorletzte und so weiter. Listing 11 stellt die Ausgaben von Cat und Tac gegenüber.

Listing 11

$ cat adressen
CH-1000 Lausanne
D-20000 Hamburg
F-25000 Besancon
ZA-8000 Cape Town
$ tac adressen
ZA-8000 Cape Town
F-25000 Besancon
D-20000 Hamburg
CH-1000 Lausanne

Shuf und Unsort

Die beiden Kommandos Shuf (aus dem Paket coreutils) und Unsort (aus dem gleichnamigen Paket) erzeugen eine zufällige Folge (“shuffle”) von Zahlen oder Zeilen. Der erste Aufruf in Listing 12 demonstriert das mithilfe des Schalters -i (--input-range) für die Zahlen von 1 bis 5.

Shuf kann aber noch mehr: Mit dem Schalter -n (--head-lines) begrenzen Sie die Ausgabe auf die angegebene Anzahl. Damit gelingt dann so etwas wie “5 aus 25” (zweiter Aufruf).

Listing 12

$ shuf -i 1-5
2
5
1
4
3
$ shuf -i 1-25 -n 5
10
24
9
16
21

Wie eingangs erwähnt, klappt das nicht nur mit Zahlen, sondern auch mit Zeilen aus einer Datei oder als Ergebnis eines Kommandos, beispielsweise von Audiodateien. Listing 13 zeigt Unsort in Kombination mit Find, Xargs und Cvlc (der Kommandozeilenschnittstelle des Mediaplayers VLC). Find durchstöbert Ihre Audiodateien, Unsort würfelt deren Reihenfolge durcheinander, und Xargs [4] ruft den Player Cvlc mit jeder einzelnen gefundenen Datei auf. Somit erreichen Sie ohne viel Aufwand einen perfekten Mix.

Listing 13

$ find . -name '*.mp3' -print0 | unsort -0 | xargs -0 cvlc

Der Hauptunterschied zwischen Shuf und Unsort liegt darin, dass nur Shuf Zahlenreihen generieren kann. Unsort vermag dafür aber auf mehr als einer Datei zu operieren und erlaubt es zudem, den verwendeten Zufallsmodus genauer einzustellen.

Expand / Unexpand

Das Kommando Expand liest Textdateien und expandiert jedes vorkommende Tabulatorzeichen. Dafür nutzt es eine entsprechende Anzahl von Leerzeichen. Unexpand bewirkt das exakte Gegenteil: Es ersetzt eine angegebene Anzahl von Leerzeichen jeweils durch einen Tabulator.

Die beiden Kommandos aus dem Paket coreutils kommen ins Spiel, wenn Sie Daten austauschen und auf verschiedenen Systemen verarbeiten möchten, da die Anzahl der Leerzeichen pro Tabulator nicht überall gleich ausfällt und viele Programme das eigenständig handhaben.

Expand und Unexpand nutzen in der Standardeinstellung 8 Zeichen pro Tabulator. Listing 14 zeigt zuerst die Originaldatei und darunter den Aufruf von Expand. Die Angabe -t 10 sorgt für eine Tabulatorbreite von 10 Zeichen.

Listing 14

$ cat names3
Nummer  Name
15672   Anna Fischer
31984   Holger Meier
21564   Werner Baumgarten
15670   Gottfried Scherz
$ expand -t 10 names3
Nummer    Name
15672     Anna Fischer
31984     Holger Meier
21564     Werner Baumgarten
15670     Gottfried Scherz

Numfmt

Immer wieder tauchen im Alltag Zahlenwerte auf, die man in unterschiedliche Darstellungen umwandeln muss – im einfachsten Fall in eine für den Menschen gut lesbare Form (“human readable”).

Das Werkzeug Numfmt aus dem Paket coreutils leistet das und kann insbesondere zwischen der SI- und der IEC-Darstellung umrechnen, also zwischen der Basis 1000 und der Basis 1024. Einige Beispiele dazu zeigt die Tabelle “Numfmt: Umwandlungen”. Die Konvertierung umfasst gegebenenfalls auch die landes- beziehungsweise sprachspezifischen Trennzeichen für die Tausender: Numfmt setzt hier je nach der locale-Einstellung des Systems Punkte oder Kommas.

Umwandlung

Aufruf

Ergebnis

von SI

numfmt --from=si 1K

1000

von IEC

numfmt --from=iec 1K

1024

von IEC-i

numfmt --from=iec-i 1Ki

1024

nach SI

numfmt --to=si 2048

2,1K

nach IEC

numfmt --to=iec 2048

2,0K

nach IEC-i

numfmt --to=iec-i 2048

2,0Ki

Zu den nützlichen Schaltern zählen beispielsweise --header für eine Kopfzeile, die Numfmt dann nicht verändert, und --field=Zahl, was die Umwandlung auf die angegebene Spalte begrenzt. Listing 15 demonstriert das für einen zweizeiligen Tabellenkopf und eine Konversion nur in der zweiten Spalte.

Listing 15

$ cat sales | numfmt --header=2 --field 2 --to=si
Produkt Anzahl
--------------
Schuhe    146K
Hüte      5,7K
Socken     32K
Hosen     516K

Fazit

Die hier vorgestellten Werkzeuge schließen diverse Lücken, die die bekannteren Werkzeuge lassen, und ergänzen die klassischen Tools dabei auf nützliche Weise. Damit erleichtern sie die Alltagsarbeit auf der Kommandozeile und beim Skripting in vielen Fällen ganz erheblich. 

Die Autoren

Der digitale Nomade Frank Hofmann agiert bevorzugt von Berlin, Genf und Kapstadt aus als Entwickler, LPI-zertifizierter Trainer und Autor. Der Linux-Sysadmin und Spezialist für Netzwerksicherheit Axel Beckert arbeitet bei den Informatikdiensten der ETH und engagiert sich ehrenamtlich bei Debian sowie in diversen Open-Source-Projekten. Beide haben zusammen das Debian-Paketmanagement-Buch (http://www.dpmb.org) verfasst.

Infos

  1. Coreutils: https://packages.debian.org/coreutils

  2. Flattersatz: https://www.repetico.de/card-59230948

  3. “Wie vermeidet man Löcher im Text im Blocksatz?”: https://opusdesign.de/blog-post/blocksatz-loecher-im-text-vermeiden/

  4. Xargs: Axel Beckert, “Häppchenweise”, LU 02/2015, S. 92, https://www.linux-community.de/31454

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 03/2019 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben