JSON und YAML sehen harmlos aus, bis du sie mit `grep`, `cut` und drei verzweifelten `awk`-Einzeilern bearbeiten willst. Dann wird aus DevOps schnell DevOops. Wir haben uns deshalb mal wieder `jq` und `yq` auf die Shell gelegt – zwei Werkzeuge, die strukturierte Daten nicht wie Text behandeln, sondern wie das, was sie sind: strukturierte Daten.
`jq` ist der Klassiker für JSON. Installation ist meistens unspektakulär:
```bash
apt install jq
brew install jq
```
Testobjekt:
```json
{
"services": [
{"name": "web", "port": 443, "enabled": true},
{"name": "db", "port": 5432, "enabled": false},
{"name": "api", "port": 8080, "enabled": true}
]
}
```
Speichern wir als `services.json`. Der erste Reflex:
```bash
jq '.' services.json
```
Das formatiert JSON lesbar. Schon nett. Aber wir wollen ja nicht nur hübsch anschauen, sondern Daten aus dem Gebüsch ziehen:
```bash
jq '.services[].name' services.json
```
Gibt alle Namen aus. Mit `-r` ohne Anführungszeichen, also pipeline-freundlich:
```bash
jq -r '.services[].name' services.json
```
Filtern? Klar:
```bash
jq -r '.services[] | select(.enabled == true) | .name' services.json
```
Ergebnis:
```text
web
api
```
Das ist der Moment, in dem `grep` leise den Raum verlässt.
Auch Transformationen sind angenehm. Aus JSON wird eine kleine TSV-Liste:
```bash
jq -r '.services[] | [.name, .port, .enabled] | @tsv' services.json
```
Praktisch für Reports, Monitoring-Gefrickel oder schnelle Inventuren:
```bash
jq -r '.services[] | select(.port >= 1000) | "\(.name):\(.port)"' services.json
```
Jetzt YAML. Da kommt `yq` ins Spiel. Achtung: Es gibt mehrere `yq`-Varianten. Wir meinen hier die Go-Version von Mike Farah, die sich auf der Shell sehr angenehm benimmt:
```bash
apt install yq
brew install yq
```
Oder direkt von GitHub, falls deine Distribution noch im Museum wohnt.
Beispiel `deployment.yaml`:
```yaml
app:
name: plutex-api
replicas: 3
image: registry.example.com/api:1.4.2
env:
- name: LOG_LEVEL
value: debug
- name: FEATURE_X
value: "true"
```
Auslesen:
```bash
yq '.app.name' deployment.yaml
```
Replikas ändern, direkt auf stdout:
```bash
yq '.app.replicas = 5' deployment.yaml
```
Oder in-place, mit Sicherheitsgurt im Kopf:
```bash
yq -i '.app.replicas = 5' deployment.yaml
```
Environment-Variable filtern:
```bash
yq '.app.env[] | select(.name == "LOG_LEVEL") | .value' deployment.yaml
```
Sehr nützlich: YAML nach JSON kippen und mit `jq` weiterverarbeiten:
```bash
yq -o=json '.' deployment.yaml | jq -r '.app.image'
```
Oder andersrum JSON nach YAML:
```bash
jq '.services[] | select(.enabled)' services.json | yq -P
```
In Pipelines spielen die beiden richtig ihre Stärken aus. Beispiel: Alle aktivierten Services nehmen und daraus `curl`-Checks bauen:
```bash
jq -r '.services[] | select(.enabled) | "https://localhost:\(.port)/health"' services.json \
| while read url; do
echo "Checke $url"
curl -fsS "$url" >/dev/null || echo "Aua: $url kaputt"
done
```
Kleine Sysadmin-Regel: Wenn du strukturierte Daten hast, benutze strukturierte Werkzeuge. `grep` ist super für Logs. Für JSON und YAML ist es aber ungefähr so präzise wie ein Vorschlaghammer im Uhrmacherladen.
Unser Fazit nach dem Selbstversuch: `jq` und `yq` gehören auf jede Admin-Kiste, in jedes CI/CD-Image und in jeden Werkzeugkasten, der regelmäßig mit APIs, Kubernetes-Manifests, Configs oder Terraform-Outputs spricht. Weniger Regex-Voodoo, mehr reproduzierbare Pipelines. Genau so mögen wir das.