xargs — Argumente aus stdin zu Kommandos zusammenbauen

Praxis-Guide zu xargs: Argumente aus stdin zu Kommandos bündeln, mit -0 sicher, -I {} als Platzhalter und -P parallel ausführen.

xargs liest Daten von der Standardeingabe und baut daraus die Argumente für ein anderes Kommando zusammen – damit machst du aus Listen, die andere Werkzeuge produzieren (etwa find oder grep), im Handumdrehen ausführbare Befehle. Das ist enorm mächtig, aber auch heikel: Weil xargs die zusammengebaute Kommandozeile tatsächlich ausführt, kann ein unbedachtes xargs rm schnell mehr löschen als beabsichtigt. Besonders wichtig ist der Umgang mit Dateinamen, die Leerzeichen oder Zeilenumbrüche enthalten – dafür kombinierst du find ... -print0 mit xargs -0, sodass die Einträge NUL-getrennt und damit eindeutig übergeben werden. In diesem Guide lernst du die Optionen, die du im Alltag wirklich brauchst: vom Bündeln der Argumente über den Platzhalter -I {} bis zur parallelen Ausführung mit -P.

Grundlegende Verwendung

echo "file1 file2 file3" | xargs rm — Übergibt die Eingabewörter als Argumente an ein Kommando.

echo "file1.tmp file2.tmp" | xargs rm

<command> | xargs — Ohne Kommando nutzt xargs standardmäßig echo (fasst die Eingabe in einer Zeile zusammen).

cat urls.txt | xargs

find . -name "*.log" | xargs rm — Findet Dateien und übergibt sie als Argumente an rm.

find /var/log -name "*.log" -mtime +30 | xargs rm

cat list.txt | xargs <command> — Liest Argumente aus einer Datei (eines pro Zeile oder durch Leerzeichen getrennt).

cat servers.txt | xargs -I{} ssh {} uptime

Argumente steuern

xargs -n <max> — Verwendet höchstens max Argumente pro Kommandoaufruf.

echo "a b c d e f" | xargs -n 2 echo

xargs -L <lines> — Verwendet höchstens die angegebene Anzahl Eingabezeilen pro Kommandoaufruf.

cat urls.txt | xargs -L 1 curl -O

xargs -I{} <command> {} — Ersetzt {} durch jedes Eingabeelement. Führt das Kommando einmal pro Element aus.

cat files.txt | xargs -I{} cp {} /backup/

xargs -I@ <command> @ — Verwendet einen eigenen Platzhalter statt {}.

ls *.csv | xargs -I@ mv @ processed/

xargs -d '\n' — Verwendet den Zeilenumbruch als Trennzeichen (statt jeglichen Leerraums).

cat filelist.txt | xargs -d '\n' rm

xargs -0 — Verwendet das Null-Zeichen als Trennzeichen. Passt zu find -print0 für die sichere Behandlung von Dateinamen.

find . -name "*.tmp" -print0 | xargs -0 rm

Parallele Ausführung

xargs -P <n> — Führt bis zu n Prozesse parallel aus.

cat urls.txt | xargs -P 4 -I{} curl -O {}

xargs -P 0 — Führt so viele Prozesse parallel aus wie möglich.

find . -name "*.png" -print0 | xargs -0 -P 0 -I{} optipng {}

xargs -n 1 -P <n> — Verarbeitet jeweils ein Argument mit n parallelen Arbeitsprozessen.

cat servers.txt | xargs -n 1 -P 8 ping -c 1

Sichere Ausführung

xargs -p — Fragt vor jeder Kommandoausführung nach Bestätigung.

find . -name "*.bak" | xargs -p rm

xargs -t — Gibt jedes Kommando vor der Ausführung auf stderr aus (Trace-Modus).

cat files.txt | xargs -t rm

xargs --no-run-if-empty — Führt das Kommando nicht aus, wenn keine Eingabe vorliegt (GNU xargs, -r).

find . -name "*.tmp" | xargs --no-run-if-empty rm

find . -name "*.tmp" -print0 | xargs -0 rm — Sichere Behandlung von Dateinamen mit Leerzeichen, Anführungszeichen oder Sonderzeichen.

find /data -name "*.log" -print0 | xargs -0 gzip

xargs -s <size> — Setzt die maximale Kommandozeilenlänge in Bytes (vermeidet 'argument list too long').

find . -name "*.txt" | xargs -s 4096 grep 'pattern'

Typische Muster

find . -name "*.jpg" -print0 | xargs -0 -I{} convert {} -resize 50% {} — Verarbeitet jede Datei einzeln mit einem komplexen Kommando.

find ./images -name "*.jpg" -print0 | xargs -0 -I{} convert {} -resize 800x600 {}

ls *.sql | xargs -I{} mysql -u root dbname < {} — Importiert mehrere SQL-Dateien in eine Datenbank.

ls migrations/*.sql | sort | xargs -I{} mysql -u root mydb < {}

grep -rl "oldtext" . | xargs sed -i 's/oldtext/newtext/g' — Findet und ersetzt Text über mehrere Dateien hinweg.

grep -rl "http://" ./src | xargs sed -i 's|http://|https://|g'

docker ps -q | xargs docker stop — Stoppt alle laufenden Docker-Container.

docker ps -q | xargs docker stop

git diff --name-only | xargs <command> — Führt ein Kommando auf allen in git geänderten Dateien aus.

git diff --name-only | xargs prettier --write

seq 1 100 | xargs -P 10 -I{} curl -s "http://api.example.com/page/{}" -o "page-{}.html" — Lädt 100 Seiten parallel mit 10 Arbeitsprozessen herunter.

seq 1 50 | xargs -P 5 -I{} wget -q "http://example.com/img/{}.jpg"

cat hosts.txt | xargs -I{} -P 5 ssh {} 'hostname; uptime' — Führt ein Kommando parallel auf mehreren entfernten Hosts aus.

cat servers.txt | xargs -I{} -P 10 ssh -o ConnectTimeout=5 {} 'df -h /'

find . -name "*.gz" -mtime +7 -print0 | xargs -0 -r rm -v — Löscht alte komprimierte Dateien sicher und mit ausführlicher Ausgabe.

find /var/log -name "*.gz" -mtime +30 -print0 | xargs -0 -r rm -v

Fazit

xargs ist das Bindeglied, das die Ausgabe eines Kommandos in die Argumente des nächsten verwandelt – unverzichtbar, sobald du Listen aus find, grep oder git weiterverarbeiten willst. Zwei Dinge solltest du dir merken: Erstens immer find ... -print0 | xargs -0 (bzw. -d '\n') verwenden, sobald Dateinamen Leerzeichen, Anführungszeichen oder Zeilenumbrüche enthalten könnten – sonst zerlegt xargs sie an den falschen Stellen. Zweitens ist Vorsicht bei destruktiven Kommandos wie rm geboten: Teste die Pipeline zuerst mit xargs -t (zeigt das Kommando vor der Ausführung) oder ersetze das eigentliche Kommando probeweise durch echo, bevor du es scharf schaltest. Mit -I {} setzt du das Argument an beliebiger Stelle ein, mit -P N parallelisierst du – und mit -r/--no-run-if-empty vermeidest du Leerläufe bei leerer Eingabe.

Verwandte Kommandos

  • find – durchsucht Verzeichnisbäume nach Dateien und liefert die ideale Eingabe für xargs
  • grep – filtert Zeilen nach Mustern, oft als Quelle für xargs-Argumentlisten
  • tee – schreibt einen Datenstrom gleichzeitig in Datei und auf die Standardausgabe