Wofür das Script gut ist
Man schreibt einen Text, hängt an einem Wort fest, und die Suche nach einem besseren führt zuverlässig in den Browser — und von dort in irgendeinen Tab, der nichts mehr mit dem Text zu tun hat. Dieses Script beantwortet die Frage dort, wo man ohnehin gerade tippt: im Terminal.
$ synonyme.sh schnell
zügig, rasch, flink, hurtig, geschwind, in Windeseile, im Eiltempo, fix, behände, …Die Daten kommen von OpenThesaurus, einem freien deutschen Synonymwörterbuch. Das Script liest nur, ändert nichts und braucht keine Anmeldung.
Was es macht
- Fragt OpenThesaurus nach Synonymen für ein Wort (oder eine Wortgruppe)
- Gibt sie kommagetrennt aus, auf die Breite deines Terminals umgebrochen
--plaingibt einen Treffer pro Zeile — damit lässt sich das Ergebnis weiterverarbeiten
(| fzf, | grep, | head)
--limit Nkürzt die Liste,--rawliefert die JSON-Antwort unverändert- Das Suchwort selbst fliegt aus der Trefferliste, Dubletten ebenfalls
Wie es das umsetzt
Der Ursprung war eine Shell-Funktion in meiner .bashrc, die die XML-Schnittstelle mit sed und cut zerlegt hat. Beim Aufräumen für die Veröffentlichung sind drei Dinge dazugekommen, die man in einer privaten Funktion gern weglässt:
Kodierung. wget "…?q=$*" bricht, sobald das Wort einen Umlaut oder ein Leerzeichen enthält — und deutsche Wörter tun das gern. Mit curl erledigt das die Bibliothek:
curl -fsSG --max-time 10 \
--data-urlencode "q=${QUERY}" \
--data "format=application/json" \
"$API"Kein jq. Naheliegend wäre, die JSON-Antwort mit jq zu filtern — aber jq ist auf einem frischen Debian nicht installiert, und ein Script, das erst ein Paket verlangt, benutzt man kein zweites Mal. Für Felder namens "term" reicht grep vollkommen:
grep -o '"term":"[^"]*"' | cut -d'"' -f4 | grep -vixF "$QUERY" | awk '!seen[$0]++'Das awk '!seen[$0]++' ist die kürzeste Art, Dubletten zu entfernen, ohne die Reihenfolge zu zerstören — sort -u würde die Treffer alphabetisch umsortieren und damit die Rangfolge von OpenThesaurus wegwerfen.
Umbruch nur im Terminal. Das Original hat immer auf $(tput cols) umgebrochen. In einer Pipe ist das Unsinn: Da will man Zeilen, keine Optik. Deshalb wird nur umgebrochen, wenn die Ausgabe wirklich in einem Terminal landet:
if [[ -t 1 ]] && command -v tput >/dev/null && COLS=$(tput cols 2>/dev/null); thenEin Script, das anders aussieht, je nachdem ob es in ein Terminal oder in eine Pipe schreibt, ist kein Bug — es ist gutes Unix-Verhalten.
lsmacht genau dasselbe.
Warum ich das automatisiert habe
Es war nie ein Automatisierungsprojekt, sondern eine Bequemlichkeit: eine Funktion in der .bashrc, mit syn als Alias. Der Grund, sie jetzt als Script aufzuschreiben, ist ein anderer — eine .bashrc-Funktion kann man niemandem geben. Sie hat kein --help, keine Fehlerbehandlung, und sie bricht beim ersten Wort mit Umlaut. Genau das ist der Unterschied zwischen „läuft bei mir" und „kann jemand anders benutzen", und dieses kleine Script ist das kürzeste Beispiel dafür, das ich habe.
Als Shell-Funktion geht es natürlich weiterhin:
# ~/.bashrc
syn() { /usr/local/bin/synonyme.sh "$@"; }Datenschutz-Hinweis, weil er hierher gehört: Das Suchwort wird per HTTPS an openthesaurus.de übertragen. Wer das nicht will, sollte das Script nicht benutzen. Die Daten dort stehen unter CC-BY-SA.
Aufruf
synonyme.sh Haus
synonyme.sh --limit 5 schnell
synonyme.sh --plain Datei | fzf # ein Treffer pro Zeile