wc (englisch word count) zählt in Dateien oder in der Standardeingabe, wie viele Zeilen, Wörter, Zeichen und Bytes ein Text enthält. Das Tool ist in jeder Linux- und Unix-Umgebung vorinstalliert und ein Standard-Werkzeug für Shell-Skripte und Datenanalyse im Terminal.
Grundlagen
Der einfachste Aufruf liefert drei Zahlen und den Dateinamen:
$ wc brief.txt
24 152 1024 brief.txt
Die Ausgabe bedeutet: 24 Zeilen, 152 Wörter, 1024 Bytes. Über die Bash-Befehle lässt sich wc direkt in Kommandozeilen und Skripten einsetzen.
Die wichtigsten Optionen
wc -l— nur die Anzahl der Zeilen ausgebenwc -w— nur die Anzahl der Wörter ausgebenwc -m— nur die Anzahl der Zeichen ausgeben (UTF-8-korrekt)wc -c— nur die Anzahl der Bytes ausgebenwc -L— die Länge der längsten Zeile ausgeben
Typische Einsatzmuster
Sehr oft arbeitet wc mit grep, sort, uniq und cut sowie head und tail in einer Pipeline zusammen:
$ grep -c "ERROR" app.log # Anzahl der Fehlerzeilen
$ wc -l *.log # Zeilenzahl aller Logdateien
$ ls -1 | wc -l # Anzahl der Dateien im Ordner
$ cat protokoll.txt | wc -w # Wörter eines Textes zählen
Wer die Zeilen der Ausgabe eines beliebigen Befehls zählt, nutzt die Pipe: history | wc -l zeigt zum Beispiel, wie viele Einträge die Shell-Historie besitzt.
Praktische Beispiele
$ wc -l /var/log/syslog # Logzeilen zählen
$ wc -w artikel.txt # Wörter für ein Dokument
$ wc -m datei.txt # Zeichen in UTF-8 zählen
$ wc -L programm.py # längste Codezeile finden
Kombination mit xargs
Zusammen mit xargs lassen sich Ergebnisse weiterverarbeiten, etwa wenn ein Skript die Gesamtzahl der Zeilen aller Quelldateien benötigt. find liefert die Dateiliste, wc die Summe:
$ find src -name "*.py" -print0 | xargs -0 wc -l
Die Ausgabe endet mit der Gesamtsumme über alle Dateien.
Verwandte Grundlagen: Pipeline und sed-Befehle für weitere Textverarbeitung im Terminal.
Der date-Befehl zeigt das aktuelle Datum und die aktuelle Uhrzeit an und kann Datumsangaben formatieren oder berechnen. Er ist in jeder Linux- und Unix-Umgebung vorhanden und unverzichtbar für Log-Dateien, Backups und Skripte, die Zeitstempel benötigen.
Aktuelles Datum anzeigen
$ date
Mi 27. Aug 10:45:12 CEST 2026
Die Ausgabe folgt der Systemzeitzone. Mit date -u zeigt der Befehl die koordinierte Weltzeit (UTC) an — praktisch für Serververgleiche und Logs:
$ date -u
Mi 27. Aug 08:45:12 UTC 2026
Eigene Formate festlegen
Mit date +"FORMAT" lässt sich die Ausgabe frei gestalten. Die wichtigsten Platzhalter:
%Y— Jahr (z. B. 2026)%m— Monat als Zahl (01–12)%d— Tag im Monat (01–31)%H— Stunde (00–23)%M— Minute (00–59)%s— Sekunden seit dem 1. Januar 1970 (Unix-Zeitstempel)
$ date +"%Y-%m-%d"
2026-08-27
$ date +%s
1785134712
Datumswerte berechnen
Mit date -d verarbeitet der Befehl beliebige Datumsangaben:
$ date -d "2026-01-01"
Do 1. Jan 00:00:00 CET 2026
$ date -d "yesterday"
Di 26. Aug 10:45:12 CEST 2026
$ date -d "+7 days"
Do 3. Sep 10:45:12 CEST 2026
Zeitstempel in Skripten nutzen
In Bash-Skripten wird date typischerweise einer Variable zugewiesen, damit Dateinamen eindeutig werden:
backup_name="backup_$(date +%Y%m%d_%H%M%S).tar.gz"
echo "$backup_name"
So entstehen Namen wie backup_20260827_104512.tar.gz — ein bewährtes Muster für tar und gzip-Backups.
Systemzeit und Zeitzonen
Für die Systemkonfiguration von Datum, Uhrzeit und Zeitzone ist auf modernen Systemen timedatectl zuständig (siehe timedatectl-Befehle), das Teil von systemctl und journalctl aus der systemd-Welt ist:
$ timedatectl
Local time: Mi 2026-08-27 10:45:12 CEST
Universal time: Mi 2026-08-27 08:45:12 UTC
Time zone: Europe/Berlin (CEST, +0200)
System clock synchronized: yes
Verwandte Grundlagen: ps, top und kill für laufende Prozesse und df und du für Speicherplatz — auch dort spielen Zeitstempel und Laufzeiten eine Rolle.
Groovy ist eine dynamische Sprache für die Java Virtual Machine (JVM), die sich nahtlos in Java-Projekte integriert. Sie wird für Skripting, Build-Automation (Gradle), Tests und schnelle Prototypen genutzt — ohne die strikte Typsyntax von Java.
Erste Schritte
Groovy-Code wird in Dateien mit der Endung .groovy gespeichert und mit dem Interpreter groovy ausgeführt. Alternativ kompiliert man Groovy wie Java in Bytecode, der auf jeder JVM läuft.
groovy hallo.groovy # Skript direkt ausführen
groovyc Hallo.groovy # zu .class-Dateien kompilieren
groovy -e "println 'Hallo'" # Einzeiler auf der Kommandozeile
Variablen und Typen
Groovy kennt sowohl def (dynamischer Typ) als auch explizite Typen. Strings mit doppelten Anführungszeichen unterstützen Interpolation mit ${}.
def name = "Welt"
String fest = "Java"
println "Hallo ${name}" // Hallo Welt
println fest.getClass().name // java.lang.String
Listen und Maps
def liste = [1, 2, 3]
liste << 4 // Element anhängen
println liste.sum() // 10
def map = [name: "Devon", ort: "Lübeck"]
println map.name // Devon
Kontrollstrukturen
for (i in 1..5) { print "$i " } // 1 2 3 4 5
(1..3).each { n -> println n } // Iteration mit Closure
def x = 10
switch (x) {
case 10: println "zehn"; break
default: println "anders"
}
Closures
Closures sind anonyme Funktionen, die als Werte herumgereicht werden können — ein Kernstück von Groovy.
def verdoppeln = { int n -> n * 2 }
println verdoppeln(21) // 42
[1, 2, 3].collect { it * 10 } // [10, 20, 30]
Gradle-Builds
Groovy ist die Standardsprache für build.gradle-Dateien. Ein einfaches Projekt definiert man mit:
plugins {
id 'java'
}
repositories { mavenCentral() }
dependencies {
implementation 'com.google.guava:guava:32.1.3-jre'
}
Praxis-Tipps
- Groovy ist optional typisiert:
deffür Skripte, explizite Typen für große Codebasen. - Groovy-Code ist meist gültiges Java — umgekehrt nicht immer.
- Für schnelle Datenverarbeitung und Tests (z.B. mit Spock) ist Groovy ideal.
Mehr Grundlagen findest du unter Java-Befehle und Scala-Befehle.
Clojure ist ein moderner Lisp-Dialekt, der auf der Java Virtual Machine läuft und funktionale Programmierung mit unveränderlichen Datenstrukturen in den Mittelpunkt stellt. Er eignet sich für Webanwendungen, Datenverarbeitung und nebenläufige Systeme.
Erste Schritte
Clojure-Code wird in Dateien mit der Endung .clj gespeichert. Die REPL (Read-Eval-Print-Loop) ist der zentrale Arbeitsplatz — Code wird sofort ausgewertet.
clojure # REPL starten
clojure -M hallo.clj # Skript ausführen
lein repl # REPL über Leiningen (Build-Tool)
Basissyntax
Alles in Clojure ist ein Ausdruck in Klammern: (Funktion Argumente ...). Es gibt keine Zuweisungen im klassischen Sinne, sondern Werte und Bindungen.
(println "Hallo Welt") ; Ausgabe
(def name "Lübeck") ; globale Bindung
(let [x 10 y 20] (+ x y)) ; lokale Bindungen -> 30
(+ 1 2 3) ; 6 (Präfixnotation)
Unveränderliche Datenstrukturen
(def v [1 2 3]) ; Vektor
(conj v 4) ; [1 2 3 4] (neuer Vektor)
(def m {:name "Devon" :ort "Lübeck"})
(:name m) ; Devon
(get m :ort) ; Lübeck
Funktionen
(defn verdoppeln [n] (* n 2))
(verdoppeln 21) ; 42
(map inc [1 2 3]) ; (2 3 4)
(filter even? (range 10)) ; (0 2 4 6 8)
Nebenläufigkeit
Clojure bietet atom für geteilten, synchronisierten Zustand und future für parallele Berechnungen.
(def zaehler (atom 0))
(swap! zaehler inc) ; atomar erhöhen
@zaehler ; 1 (dereferenzieren)
(future (Thread/sleep 100) 42) ; parallele Berechnung
Praxis-Tipps
- Präfixnotation und Klammern wirken ungewohnt — nach kurzer Eingewöhnung ist die Syntax extrem konsistent.
- Unveränderliche Datenstrukturen erleichtern nebenläufige Programme enorm.
- Für Web-Entwicklung sind Ring (HTTP) und Compojure beliebte Bibliotheken.
Verwandte Grundlagen: Haskell-Befehle und Scala-Befehle.
OCaml ist eine funktionale Programmiersprache mit starkem statischem Typsystem, die auch imperative und objektorientierte Elemente bietet. Sie wird für Compiler, statische Analysen und performante Systeme eingesetzt — der Rust-Konkurrent mit anderem Ansatz.
Erste Schritte
OCaml-Code wird in Dateien mit der Endung .ml gespeichert. Die REPL heißt ocaml, als Build-Tool etabliert ist dune mit dem Paketmanager opam.
ocaml # REPL starten
ocamlc hallo.ml # Bytecode kompilieren
ocamlopt hallo.ml # nativen Code kompilieren (schneller)
opam install dune # Build-Tool installieren
Variablen und Typen
OCaml leitet Typen automatisch ab, prüft sie aber zur Compile-Zeit strikt. let bindet Namen an Werte, ;; schließt eine Top-Level-Eingabe in der REPL ab.
let name = "Welt";;
let x = 10;;
let add a b = a + b;; (* Funktionsdefinition *)
add 3 4;; (* 7 *)
Pattern Matching
Pattern Matching ersetzt in OCaml weite Teile von if/switch und ist eines der stärksten Sprachfeatures.
let beschreibe n = match n with
| 0 -> "null"
| 1 -> "eins"
| _ -> "viel";;
beschreibe 5;; (* "viel" *)
Listen und Optionen
let liste = [1; 2; 3];;
List.map (fun x -> x * 2) liste;; (* [2; 4; 6] *)
let vielleicht = Some 42;;
match vielleicht with
| Some w -> w
| None -> 0;; (* 42 *)
Unveränderlichkeit
OCaml-Daten sind standardmäßig unveränderlich. Mit ref lassen sich veränderliche Zellen erzeugen, mit Array veränderliche Felder.
let zaehler = ref 0;;
incr zaehler;; (* !zaehler ist jetzt 1 *)
let a = [|1; 2; 3|];;
a.(0) <- 99;; (* Array ist veränderlich *)
Praxis-Tipps
- Der Typinferenz-Mechanismus fängt viele Fehler bereits beim Kompilieren.
- Dune + opam sind der Standard für neue Projekte.
- F# ist die .NET-Schwester von OCaml — Konzepte übertragen sich weitgehend.
Mehr funktionale Grundlagen: F#-Befehle und Haskell-Befehle.