Quand on doit exécuter une commande sur des centaines de fichiers trouvés par find, traiter une liste depuis un fichier ou éviter l’erreur “argument list too long”, xargs est l’outil indispensable. Simple et puissant, xargs transforme l’entrée standard en arguments pour une autre commande, permettant de chaîner les commandes efficacement.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Transformer stdin en arguments pour une commande
- Limiter le nombre d’arguments avec -n
- Positionner les arguments avec -I
- Gérer les noms de fichiers avec espaces (-0)
- Exécuter des commandes en parallèle avec -P
La commande xargs dans l’écosystème Linux
Section intitulée « La commande xargs dans l’écosystème Linux »xargs fait partie des commandes de pipeline sous Linux. Chaque outil a sa spécialité :
| Commande | Spécialité | Quand l’utiliser |
|---|---|---|
xargs | Transformer stdin en arguments | Exécuter une commande sur une liste |
find | Rechercher des fichiers | Trouver par nom, taille, date |
grep | Filtrer des lignes | Rechercher des patterns |
parallel | Exécution parallèle avancée | Jobs complexes, machines distantes |
tee | Dupliquer un flux | Écrire et afficher simultanément |
xargs -P | Parallélisme simple | Jobs locaux en parallèle |
Quand utiliser xargs vs find -exec ?
| Situation | xargs | find -exec |
|---|---|---|
| Performance (moins de forks) | ✅ find | xargs cmd | ❌ Fork par fichier |
| Fichiers avec espaces | ⚠️ Nécessite -print0 | xargs -0 | ✅ Géré automatiquement |
| Exécution parallèle | ✅ -P N | ❌ |
| Syntaxe simple | ✅ | ✅ |
| Sans pipe | ❌ | ✅ -exec cmd {} \; |
Combinaisons fréquentes :
# find + xargs : supprimer des fichiers (sécurisé)find . -name "*.tmp" -print0 | xargs -0 rm
# grep + xargs : agir sur les fichiers contenant un motifgrep -rl "TODO" src/ | xargs -I {} echo "À traiter: {}"
# cat + xargs : exécuter sur une liste depuis fichiercat urls.txt | xargs -P 4 -I {} curl -O {}
# ls + xargs : renommer en massels *.bak | xargs -I {} mv {} {}.oldComprendre la commande xargs en 2 min
Section intitulée « Comprendre la commande xargs en 2 min »🧠 Modèle mental — Comment fonctionne xargs
xargs = Lire stdin → Découper en arguments → Exécuter la commande avec ces arguments
Points clés
- xargs lit stdin et transforme chaque élément en argument
- Par défaut, xargs utilise espaces et retours à la ligne comme séparateurs
- Sans commande spécifiée, xargs utilise echo par défaut
- -n limite le nombre d'arguments par exécution
- -I {} permet de positionner l'argument où on veut
- -0 avec find -print0 gère les noms de fichiers avec espaces
Règles d'or
Vocabulaire essentiel
- -n N
- Maximum N arguments par commande
- -I {}
- Remplacer {} par chaque argument
- -0
- Séparateur null (avec find -print0)
- -p
- Demander confirmation avant exécution
- -t
- Afficher la commande avant exécution
- -r
- Ne pas exécuter si stdin est vide
📚 Pour aller plus loin — 6 options avancées
- -P N
- Exécuter N commandes en parallèle
- -L N
- Maximum N lignes par commande
- -a fichier
- Lire depuis un fichier au lieu de stdin
- -d delim
- Utiliser delim comme séparateur
- --max-procs
- Alias de -P
- --no-run-if-empty
- Alias de -r
xargs lit stdin, découpe par espaces ou retours à la ligne, puis passe les éléments comme arguments à la commande spécifiée.
Syntaxe minimale
Section intitulée « Syntaxe minimale »commande_source | xargs [OPTIONS] commande_cibleLe flux de données
Section intitulée « Le flux de données »| Étape | Description | Exemple |
|---|---|---|
| 1. Source | Génère une liste | find . -name "*.log" |
| 2. Pipe | Transmet à xargs | | |
| 3. xargs | Découpe et regroupe | xargs |
| 4. Cible | Reçoit les arguments | rm → rm f1.log f2.log f3.log |
Comportement par défaut
Section intitulée « Comportement par défaut »# Sans commande : xargs utilise echoecho "a b c" | xargs# Sortie : a b c
# Avec commande : passe tous les argumentsecho "f1.txt f2.txt" | xargs rm# Équivalent à : rm f1.txt f2.txtLes options essentielles
Section intitulée « Les options essentielles »| Option | Effet | Exemple |
|---|---|---|
-n N | Maximum N arguments par exécution | xargs -n 2 |
-I {} | Utiliser comme placeholder | xargs -I {} mv {} {}.bak |
-0 | Séparateur null (avec find -print0) | find -print0 | xargs -0 |
-p | Demander confirmation | xargs -p rm |
-t | Afficher la commande (trace) | xargs -t echo |
-r | Ne pas exécuter si vide | xargs -r rm |
-P N | N processus en parallèle | xargs -P 4 |
Limiter les arguments avec -n
Section intitulée « Limiter les arguments avec -n »Par défaut, xargs passe tous les arguments en une fois. -n limite :
# Tous les argumentsecho "1 2 3 4 5 6" | xargs echo# Sortie : 1 2 3 4 5 6
# 2 arguments par exécutionecho "1 2 3 4 5 6" | xargs -n 2 echo# Sortie :# 1 2# 3 4# 5 6Positionner l’argument avec -I
Section intitulée « Positionner l’argument avec -I »Par défaut, xargs ajoute les arguments à la fin. -I {} permet de les positionner :
# Sans -I : arguments à la finecho "file.txt" | xargs cp /backup/# → cp /backup/ file.txt (ERREUR !)
# Avec -I : contrôle du placementecho "file.txt" | xargs -I {} cp {} /backup/{}# → cp file.txt /backup/file.txt ✓Note : -I implique -n 1 (un argument par exécution).
Gérer les espaces avec -0
Section intitulée « Gérer les espaces avec -0 »Les noms de fichiers avec espaces cassent xargs par défaut :
# ❌ DANGER : "mon fichier.txt" devient 2 argumentsfind . -name "*.txt" | xargs rm# rm essaie de supprimer "mon" et "fichier.txt" séparément !
# ✅ SÉCURISÉ : séparateur nullfind . -name "*.txt" -print0 | xargs -0 rm# Gère correctement "mon fichier.txt"Tester avant d’exécuter
Section intitulée « Tester avant d’exécuter »Règle d’or : toujours tester avec echo ou -p d’abord !
# 1. Voir ce qui serait exécutéfind . -name "*.tmp" | xargs echo rm
# 2. Demander confirmationfind . -name "*.tmp" | xargs -p rm
# 3. Exécuter (si ok)find . -name "*.tmp" -print0 | xargs -0 rmExécution parallèle avec -P
Section intitulée « Exécution parallèle avec -P »# Télécharger 4 URLs en parallèlecat urls.txt | xargs -P 4 -I {} curl -O {}
# Compresser des fichiers en parallèle (4 processus)find . -name "*.log" -print0 | xargs -0 -P 4 gzipErreurs typiques (et solutions)
Section intitulée « Erreurs typiques (et solutions) »| Erreur | Cause | Solution |
|---|---|---|
| ”No such file” avec espaces | Découpage incorrect | -print0 | xargs -0 |
| Commande exécutée sans argument | stdin vide | Ajouter -r |
| ”Argument list too long” | Trop de fichiers | xargs découpe automatiquement (ou -n) |
| non remplacé | Oubli de -I | Ajouter -I {} |
| Résultat mélangé en parallèle | Sorties entremêlées | Rediriger vers fichiers séparés |
Les Modèles d’utilisation courants
Section intitulée « Les Modèles d’utilisation courants »Maintenant que vous comprenez la logique de xargs, voici des modèles courants
pour des traitements fréquents.
Ces recettes couvrent les cas d'usage les plus fréquents. Cliquez sur un pattern pour voir la formule complète et un exemple prêt à copier.
Transformation basique Base Passer une liste comme arguments à une commande.
echo "file1.txt file2.txt" | xargs rm
echo "a b c" | xargs <commande> echo "file1.txt file2.txt" | xargs rm -
commande— Commande qui reçoit les arguments
Lire depuis un fichier Base Traiter une liste de fichiers depuis un fichier texte.
cat fichiers.txt | xargs rm
cat <liste> | xargs <commande> cat fichiers.txt | xargs rm -
liste— Fichier contenant la liste
Limiter les arguments Base Exécuter la commande avec N arguments maximum.
echo "1 2 3 4 5 6" | xargs -n 2 echo
xargs -n N <commande> echo "1 2 3 4 5 6" | xargs -n 2 echo -
-n N— Maximum N arguments par exécution
Positionner l'argument Inter. Utiliser l'argument à un emplacement spécifique.
ls *.txt | xargs -I {} mv {} {}.bak
xargs -I {} <commande avec {}> ls *.txt | xargs -I {} mv {} {}.bak -
-I {}— Remplace {} par l'argument
Séparateur null (espaces dans noms) Inter. Gérer les noms de fichiers avec espaces.
find . -name "*.txt" -print0 | xargs -0 rm
find . -print0 | xargs -0 <commande> find . -name "*.txt" -print0 | xargs -0 rm -
-print0— find produit des nuls -
-0— xargs lit des nuls
Confirmation interactive Base Demander confirmation avant chaque exécution.
echo "file1 file2" | xargs -p rm
xargs -p <commande> echo "file1 file2" | xargs -p rm -
-p— Prompt avant exécution
Mode verbeux Base Afficher la commande avant exécution.
echo "1 2 3" | xargs -t -n 1 echo
xargs -t <commande> echo "1 2 3" | xargs -t -n 1 echo -
-t— Trace (affiche la commande)
Éviter exécution sur vide Base Ne pas exécuter si stdin est vide.
find . -name "*.xyz" | xargs -r rm
xargs -r <commande> find . -name "*.xyz" | xargs -r rm -
-r— No run if empty
Exécution parallèle Avancé Exécuter plusieurs commandes en parallèle.
cat urls.txt | xargs -P 4 -I {} curl -O {}
xargs -P N <commande> cat urls.txt | xargs -P 4 -I {} curl -O {} -
-P N— N processus en parallèle
find + xargs + rm Inter. Supprimer des fichiers trouvés par find.
find /tmp -name "*.tmp" -print0 | xargs -0 rm
find <chemin> -name "<pattern>" -print0 | xargs -0 rm find /tmp -name "*.tmp" -print0 | xargs -0 rm -
chemin— Répertoire de recherche -
pattern— Motif de fichiers
find + xargs + grep Inter. Rechercher du texte dans les fichiers trouvés.
find . -name "*.py" -print0 | xargs -0 grep "import"
find . -name "<pattern>" -print0 | xargs -0 grep "<motif>" find . -name "*.py" -print0 | xargs -0 grep "import" -
pattern— Type de fichiers -
motif— Texte à rechercher
Renommer en masse Inter. Renommer plusieurs fichiers avec un pattern.
ls *.bak | xargs -I {} mv {} {}.old
ls <pattern> | xargs -I {} mv {} <nouveau_pattern> ls *.bak | xargs -I {} mv {} {}.old -
pattern— Fichiers à renommer -
nouveau_pattern— Nouveau nom/extension
Créer une archive Inter. Archiver des fichiers trouvés.
find . -name "*.log" -print0 | xargs -0 tar -czvf logs.tar.gz
find . -name "<pattern>" -print0 | xargs -0 tar -czvf <archive> find . -name "*.log" -print0 | xargs -0 tar -czvf logs.tar.gz -
pattern— Fichiers à archiver -
archive— Nom de l'archive
Changer les permissions en masse Inter. Appliquer chmod sur plusieurs fichiers.
find . -type f -name "*.sh" -print0 | xargs -0 chmod +x
find . -type f -name "<pattern>" -print0 | xargs -0 chmod <mode> find . -type f -name "*.sh" -print0 | xargs -0 chmod +x -
pattern— Fichiers à modifier -
mode— Nouvelles permissions
Aucune recette ne correspond à votre recherche.
Les Pièges à éviter
Section intitulée « Les Pièges à éviter »Ces erreurs courantes peuvent faire perdre du temps ou causer des dégâts. Les pièges les plus critiques sont affichés en premier.
Noms de fichiers avec espaces find . -name "*.txt" | xargs rm (échoue si "mon fichier.txt")
Danger
find . -name "*.txt" | xargs rm (échoue si "mon fichier.txt")
find . -name "*.txt" -print0 | xargs -0 rm Exécuter sans tester cat liste.txt | xargs rm (suppression immédiate)
Danger
cat liste.txt | xargs rm (suppression immédiate)
cat liste.txt | xargs echo rm # puis xargs -p rm Exécution sur entrée vide find . -name "*.xyz" | xargs rm (exécute "rm" sans argument)
Attention
find . -name "*.xyz" | xargs rm (exécute "rm" sans argument)
find . -name "*.xyz" | xargs -r rm Dépassement de la limite d'arguments find / -type f | xargs ls (trop de fichiers)
Attention
find / -type f | xargs ls (trop de fichiers)
find / -type f -print0 | xargs -0 -n 1000 ls Oubli de -I avec placeholder ls *.txt | xargs mv {} backup/ (erreur de syntaxe)
Attention
ls *.txt | xargs mv {} backup/ (erreur de syntaxe)
ls *.txt | xargs -I {} mv {} backup/ Commande introuvable avec -I ls | xargs -I {} echo {} | wc -l (pipe après -I)
Attention
ls | xargs -I {} echo {} | wc -l (pipe après -I)
ls | xargs -I {} sh -c 'echo {} | wc -c' Sortie mélangée en parallèle xargs -P 4 commande (sorties entremêlées)
Info
xargs -P 4 commande (sorties entremêlées)
xargs -P 4 -I {} sh -c 'commande {} > {}.out' Expansion des guillemets echo "a b" "c d" | xargs -n 1 (4 arguments au lieu de 2)
Info
echo "a b" "c d" | xargs -n 1 (4 arguments au lieu de 2)
printf "a b\0c d" | xargs -0 -n 1 Cheatsheet
Section intitulée « Cheatsheet » 📋
Cheatsheet xargs
📝 Syntaxe :
cmd | xargs Transformer stdin en arguments 🚀 Commandes types :
echo "file1.txt file2.txt" | xargs rm cat fichiers.txt | xargs rm echo "1 2 3 4 5 6" | xargs -n 2 echo echo "file1 file2" | xargs -p rm echo "1 2 3" | xargs -t -n 1 echo ⚙️ Options
xargs -n N | Maximum N arguments par exécution | xargs -n 2 |
xargs -I {} | Utiliser {} comme placeholder | xargs -I {} mv {} {}.bak |
xargs -0 | Séparateur null (avec find -print0) | find . -print0 | xargs -0 |
xargs -p | Confirmation avant exécution | xargs -p rm |
xargs -t | Afficher la commande (trace) | xargs -t echo |
xargs -r | Ne pas exécuter si vide | xargs -r rm |
xargs -P N | N processus en parallèle | xargs -P 4 |
xargs -L N | Maximum N lignes par exécution | xargs -L 1 |
xargs -a fichier | Lire depuis fichier | xargs -a liste.txt rm |
xargs -d delim | Utiliser delim comme séparateur | xargs -d "," |
🔗 Composition
find -print0 | xargs -0 | Pattern sécurisé pour fichiers | find . -name "*.txt" -print0 | xargs -0 rm |
xargs -I {} sh -c '...' | Commande complexe avec pipes | xargs -I {} sh -c 'cat {} | wc -l' |
xargs echo | Tester sans exécuter | cat liste | xargs echo rm |
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Conclusion
Section intitulée « Conclusion »La commande xargs est le chaînon manquant entre les commandes qui produisent des listes (find, grep -l, cat) et celles qui attendent des arguments (rm, mv, cp). Ses options clés sont -0 (sécurité avec les espaces), -I {} (positionnement), -n (limitation) et -P (parallélisme). Pour des besoins plus avancés (machines distantes, jobs complexes), explorez parallel.
FAQ - Questions Fréquemment Posées
Section intitulée « FAQ - Questions Fréquemment Posées »Définition
xargs (eXtended ARGumentS) transforme l'entrée standard (stdin) en arguments de ligne de commande pour exécuter des commandes sur des listes d'items.| Caractéristique | Description |
|---|---|
| Fonction | Convertir stdin → arguments CLI |
| Usage typique | Pipeline avec find, grep, ls |
| Problème résolu | Limite ARG_MAX (taille max arguments) |
| Traitement | Batch processing automatique |
| Sécurité | Gestion noms fichiers spéciaux (-0) |
Concept pipeline
# Sans xargs (impossible)
rm $(find . -name "*.tmp") # ❌ Échoue si trop de fichiers
# Avec xargs (robuste)
find . -name "*.tmp" | xargs rm # ✅ Batch automatique
Exemples basiques
# 1. Compter fichiers
find . -name "*.txt" | xargs wc -l
# 2. Copier fichiers
ls *.log | xargs -I {} cp {} /backup/
# 3. Chercher pattern
find . -type f | xargs grep "ERROR"
# 4. Supprimer vieux fichiers
find /tmp -mtime +7 | xargs rm
Cas DevOps
Contexte : Indispensable pour automatiser opérations massives sur fichiers.Problème ARG_MAX
# Limite système arguments
getconf ARG_MAX # Ex: 2097152 bytes (2 Mo)
# ❌ ÉCHOUE si trop de fichiers
rm *.log # Erreur: Argument list too long
# ✅ FONCTIONNE avec xargs
find . -name "*.log" | xargs rm
Avantages xargs
| Avantage | Description | Exemple |
|---|---|---|
| Batch processing | Découpe automatiquement en lots | xargs -n 100 |
| Limite ARG_MAX | Contourne limite système | Fichiers illimités |
| Parallélisation | Exécution simultanée (-P) | xargs -P 4 |
| Sécurité noms | Gère espaces/newlines (-0) | xargs -0 |
| Performance | Moins de fork() que boucles | 10-100x plus rapide |
Comparaison boucle vs xargs
# ❌ Boucle shell (lent, 1 fork par fichier)
for file in *.txt; do
gzip "$file"
done
# ✅ xargs (rapide, batch processing)
ls *.txt | xargs gzip
# ✅ xargs parallèle (très rapide)
ls *.txt | xargs -P 4 gzip # 4 processus simultanés
Cas pratiques
# CI/CD : nettoyer old Docker images
docker images -q -f "dangling=true" | xargs docker rmi
# Logs : compresser fichiers anciens
find /var/log -name "*.log" -mtime +30 | xargs gzip
# Kubernetes : delete failed pods
kubectl get pods -o name | grep Failed | xargs kubectl delete
# Git : chercher pattern dans tous repos
find ~/projects -name .git -type d | xargs -I {} git -C {} log --grep="bug"
Performance
# Benchmark : 10000 fichiers
time for f in *.txt; do wc -l "$f"; done # ~45s
time ls *.txt | xargs wc -l # ~2s
time ls *.txt | xargs -P 4 wc -l # ~0.5s
Règle : xargs obligatoire pour opérations massives (>1000 fichiers).Structure syntaxe
# Pattern de base
commande_source | xargs [OPTIONS] commande_destination
└─stdin └─args └─exécutée avec args
# Exemples
echo "file1 file2" | xargs ls -l
find . -name "*.log" | xargs grep ERROR
cat urls.txt | xargs curl -O
Options principales
| Option | Usage | Exemple |
|---|---|---|
-n NUM |
Max arguments par exec | xargs -n 5 |
-I {} |
Placeholder replacement | xargs -I {} mv {} /dest/ |
-0 |
Null-terminated input | find -print0 | xargs -0 |
-P NUM |
Parallel processes | xargs -P 4 |
-t |
Print command before exec | xargs -t rm |
-p |
Prompt before exec | xargs -p rm |
-r |
No run if empty | xargs -r command |
Sources stdin courantes
# find (le plus fréquent)
find /var/log -name "*.log" | xargs grep ERROR
# cat fichier
cat file_list.txt | xargs cp -t /backup/
# echo
echo "file1 file2 file3" | xargs ls -l
# ls
ls *.txt | xargs wc -l
# grep
grep -l "TODO" *.md | xargs vim
Exemples progressifs
# 1. Basique (echo par défaut)
echo "a b c" | xargs
# Sortie: a b c
# 2. Commande simple
echo "file1.txt file2.txt" | xargs cat
# 3. Avec options
echo "1 2 3 4" | xargs -n 2 echo
# Sortie: 1 2
# 3 4
# 4. Placeholder
echo "*.log" | xargs -I {} mv {} /backup/{}
# 5. Parallèle
find . -name "*.jpg" | xargs -P 4 -I {} convert {} {}.png
DevOps patterns
# Docker cleanup
docker ps -a -q -f status=exited | xargs docker rm
# Kubernetes logs
kubectl get pods -o name | xargs -I {} kubectl logs {}
# Git multi-repo
find ~/projects -name .git | xargs -I {} git -C {}/../ pull
Pattern : source | xargs [options] destination.Option -n (max-args)
# Syntaxe
xargs -n NUMBER command
# Exemple basique
echo "1 2 3 4 5 6" | xargs -n 2 echo
# Exécute:
# echo 1 2
# echo 3 4
# echo 5 6
Comportement
| -n VALUE | Effet | Exécutions |
|---|---|---|
-n 1 |
1 arg par commande | Autant d'execs que d'args |
-n 5 |
5 args par commande | Total args / 5 |
-n 100 |
100 args max | Batch de 100 |
| (défaut) | Tous les args possibles | 1 exec (ou selon ARG_MAX) |
Exemples pratiques
# Traiter fichiers 1 par 1
ls *.txt | xargs -n 1 gzip
# gzip file1.txt
# gzip file2.txt
# gzip file3.txt
# Copier par paires
echo "src1 dest1 src2 dest2" | xargs -n 2 cp
# cp src1 dest1
# cp src2 dest2
# Batch de 50 pour performance
find . -name "*.log" | xargs -n 50 tar -czf logs.tar.gz
Cas DevOps
# Docker : remove images 10 par 10
docker images -q | xargs -n 10 docker rmi
# Kubernetes : restart pods 1 par 1 (rolling)
kubectl get pods -o name | xargs -n 1 kubectl delete
# Monitoring : check URLs 5 simultanées
cat urls.txt | xargs -n 1 -P 5 curl -I
# Backup : archiver par groupes de 100 fichiers
find /data -type f | xargs -n 100 tar -rf backup.tar
Combinaison -n et -P
# 4 processus, 1 fichier chacun
ls *.mp4 | xargs -n 1 -P 4 ffmpeg -i {} {}.webm
# Parallélisme contrôlé
find . -name "*.jpg" | xargs -n 5 -P 2 mogrify -resize 50%
# 2 processus simultanés, 5 images chacun
Debug avec -n 1
# Voir chaque exécution
find . -name "*.tmp" | xargs -n 1 -t rm
# rm ./file1.tmp
# rm ./file2.tmp
# ...
Astuce : -n 1 = le plus safe (1 arg = 1 exécution), utile pour debug.Option -p (prompt)
# Syntaxe
xargs -p command
# Exemple
find . -name "*.tmp" | xargs -p rm
# rm ./cache.tmp ?...y
# rm ./old.tmp ?...n (skip)
# rm ./test.tmp ?...y
Workflow interactif
# 1. Affiche commande complète
echo "file1 file2" | xargs -p rm
# Prompt: rm file1 file2 ?...
# 2. Attendre réponse utilisateur
# y/Y = yes → exécute
# n/N = no → skip
# Ctrl+C = abort tout
# 3. Répète pour chaque batch
Cas d'usage sécurité
# Suppression sécurisée
find /var/log -name "*.log" -mtime +90 | xargs -p rm
# Modification base données
cat user_ids.txt | xargs -p -I {} psql -c "DELETE FROM users WHERE id={}"
# Docker cleanup
docker ps -a -q | xargs -p docker rm
# Kubernetes delete
kubectl get pods -o name | grep test | xargs -p kubectl delete
Combinaison -p et -n
# Confirmer fichier par fichier
ls *.bak | xargs -n 1 -p rm
# rm file1.bak ?...y
# rm file2.bak ?...n
# rm file3.bak ?...y
Alternative : -t (verbose)
# -t : affiche sans demander
find . -name "*.tmp" | xargs -t rm
# rm ./cache.tmp ./old.tmp ./test.tmp
# (exécute directement)
# Combinaison -t + dry-run
find . -name "*.log" | xargs -t echo rm
# echo rm file1.log file2.log
# (simulation, pas d'exécution réelle)
Pattern sécurité
# 1. Test avec echo
find . -name "*.old" | xargs echo rm
# 2. Vérification avec -t
find . -name "*.old" | xargs -t rm --dry-run 2>/dev/null || true
# 3. Exécution avec -p
find . -name "*.old" | xargs -p rm
# 4. Exécution finale
find . -name "*.old" | xargs rm
Règle : Toujours -p ou -t pour commandes destructives (rm, docker rmi, kubectl delete).Option -I (replace-str)
# Syntaxe
xargs -I PLACEHOLDER command PLACEHOLDER [PLACEHOLDER ...]
# Convention : {} comme placeholder
xargs -I {} command arg1 {} arg2 {}
Exemples basiques
# Déplacer fichiers
ls *.txt | xargs -I {} mv {} /backup/{}
# Copier avec renommage
ls *.log | xargs -I {} cp {} {}.backup
# Créer arborescence
cat dirs.txt | xargs -I {} mkdir -p /data/{}
# Multiples occurrences
echo "app" | xargs -I {} docker run -v {}:/app --name {} myimage
Patterns courants
| Pattern | Commande | Résultat |
|---|---|---|
| Backup | xargs -I {} cp {} {}.bak |
file.txt → file.txt.bak |
| Rename | xargs -I {} mv {} new_{} |
file.txt → new_file.txt |
| Directory | xargs -I {} mv {} /dest/{} |
Déplace vers /dest/ |
| Extension | xargs -I {} convert {} {}.png |
.jpg → .jpg.png |
| Multiple | xargs -I {} cp {} /a/{} /b/{} |
Copie vers 2 destinations |
Transformation noms
# Préfixe
ls *.md | xargs -I {} mv {} docs_{}
# Suffixe
ls *.jpg | xargs -I {} convert {} {}_thumb.jpg
# Substitution (avec bash)
ls *.txt | xargs -I {} bash -c 'mv {} $(echo {} | sed s/.txt/.md/)'
# Extension change
find . -name "*.jpeg" | xargs -I {} mv {} {}.jpg
Cas DevOps
# Docker : tag images
docker images -q | xargs -I {} docker tag {} registry.io/{}:latest
# Kubernetes : copy secrets
kubectl get secrets -o name | xargs -I {} kubectl get {} -o yaml > {}.yaml
# Git : clone multiple repos
cat repos.txt | xargs -I {} git clone https://github.com/org/{}
# Backup avec timestamp
find . -name "*.conf" | xargs -I {} cp {} {}.$(date +%Y%m%d)
# AWS S3 : download objects
aws s3 ls s3://bucket/ | awk '{print $4}' | xargs -I {} aws s3 cp s3://bucket/{} ./{}
Placeholder custom
# Utiliser autre symbole que {}
ls *.log | xargs -I FILE mv FILE /backup/FILE
ls *.txt | xargs -I @ echo "Processing @"
Différence avec position args
# Sans -I (args à la fin)
ls *.txt | xargs grep ERROR
# grep ERROR file1.txt file2.txt
# Avec -I (contrôle position)
ls *.txt | xargs -I {} grep ERROR {}
# grep ERROR file1.txt
# grep ERROR file2.txt
Astuce : -I {} permet réutilisation même argument plusieurs fois dans commande.Problème espaces/newlines
# ❌ ÉCHOUE avec espaces
find . -name "*.txt" | xargs rm
# Fichier: "My Document.txt"
# Interprété comme: rm My Document.txt (2 fichiers !)
# ✅ FONCTIONNE avec -0
find . -name "*.txt" -print0 | xargs -0 rm
# Fichier traité correctement: "My Document.txt"
Séparateurs
| Méthode | Séparateur | Problèmes |
|---|---|---|
| Défaut | Espace/tab/newline | ❌ Casse noms avec espaces |
| -0 | Null byte (\0) | ✅ Sûr pour tous caractères |
find -print0 + xargs -0
# Pattern standard (TOUJOURS utiliser)
find [path] [tests] -print0 | xargs -0 [command]
# Exemples
find . -name "* *.txt" -print0 | xargs -0 rm
find /backup -mtime +30 -print0 | xargs -0 gzip
find . -type f -print0 | xargs -0 grep "ERROR"
Cas problématiques
# Fichiers avec:
# - Espaces: "My File.txt"
# - Newlines: "File\nWith\nBreaks.txt"
# - Tabs: "File\tName.txt"
# - Quotes: "File'With"Quotes.txt"
# ❌ Sans -0
find . -type f | xargs wc -l # ÉCHOUE
# ✅ Avec -0
find . -type f -print0 | xargs -0 wc -l # OK
Autres sources null-terminated
# GNU tools supportent -0
grep -lZ "pattern" *.txt | xargs -0 vim
locate -0 "*.conf" | xargs -0 cat
sort -z file.txt | xargs -0 process
# tr pour convertir
cat list.txt | tr '\n' '\0' | xargs -0 rm
DevOps exemples
# Git : fichiers modifiés avec espaces
git ls-files -z -m | xargs -0 git add
# Docker : cleanup avec labels
docker ps -aq --filter "label=env=test" | tr '\n' '\0' | xargs -0 docker rm
# Kubernetes : logs pods avec espaces namespace
kubectl get pods -o name | tr '\n' '\0' | xargs -0 -I {} kubectl logs {}
# Backup fichiers récents
find /data -mtime -1 -print0 | xargs -0 tar -czf backup.tar.gz --files-from=-
Test sécurité
# Créer fichier test avec espace
touch "My Test File.txt"
# ❌ Sans -0 (détecte 3 fichiers!)
find . -name "*.txt" | xargs ls
# ls: My: No such file
# ls: Test: No such file
# ls: File.txt: No such file
# ✅ Avec -0 (OK)
find . -name "*.txt" -print0 | xargs -0 ls
# ./My Test File.txt
RÈGLE CRITIQUE : TOUJOURS -print0 | xargs -0 avec find pour éviter bugs.Option -t (verbose/trace)
# Syntaxe
xargs -t command
# Exemple
echo "file1 file2" | xargs -t rm
# Output stderr: rm file1 file2
# (puis exécute)
Comportement
# Affiche commande complète sur stderr
find . -name "*.tmp" | xargs -t rm
# rm ./cache.tmp ./old.tmp
# rm ./test.tmp
# Chaque batch affiché
echo "1 2 3 4" | xargs -n 2 -t echo
# echo 1 2
# 1 2
# echo 3 4
# 3 4
Cas d'usage debug
# Vérifier arguments passés
find /var/log -name "*.log" | xargs -t wc -l
# Affiche: wc -l /var/log/app.log /var/log/system.log ...
# Tracer exécutions multiples
ls *.txt | xargs -n 1 -t gzip
# gzip file1.txt
# gzip file2.txt
# gzip file3.txt
Logging production
# Rediriger traces vers log
find . -name "*.old" | xargs -t rm 2>> cleanup.log
# Timestamp logs
find /data -mtime +30 | xargs -t -I {} \
bash -c 'echo "$(date): Deleting {}" >> audit.log && rm {}'
# Monitoring progressif
find . -name "*.jpg" | xargs -t -P 4 -I {} convert {} {}.png 2>&1 | tee progress.log
Dry-run simulation
# Test sans exécution réelle
find . -name "*.bak" | xargs -t echo rm
# echo rm file1.bak file2.bak
# file1.bak file2.bak
# (affiche mais N'exécute PAS rm)
# Alternative dry-run
find . -type f | xargs -t -I {} echo "Would delete: {}"
DevOps patterns
# Docker : voir images supprimées
docker images -q -f dangling=true | xargs -t docker rmi
# docker rmi sha256:abc123 sha256:def456
# Kubernetes : trace deletions
kubectl get pods -o name | grep test | xargs -t kubectl delete
# kubectl delete pod/test-1 pod/test-2
# CI/CD : log deployment steps
cat artifacts.txt | xargs -t -I {} scp {} deploy@server:/app/
# scp app.jar deploy@server:/app/
# scp config.yml deploy@server:/app/
# Git : trace multi-repo pulls
find ~/projects -name .git -type d | xargs -t -I {} git -C {}/../ pull
Combinaison -t et -p
# Afficher ET confirmer
find . -name "*.tmp" | xargs -t -p rm
# rm ./cache.tmp ?...y
# (affiche puis demande confirmation)
Performance monitoring
# Avec time pour chaque commande
ls *.log | xargs -n 1 -t -I {} bash -c 'time gzip {}'
# Parallèle avec traces
find . -name "*.mp4" | xargs -t -P 4 -I {} ffmpeg -i {} {}.webm
Astuce : -t essentiel pour debugging pipelines complexes find | xargs.Comportement par défaut : echo
# Sans commande → echo implicite
echo "a b c" | xargs
# Sortie: a b c
# Équivalent à
echo "a b c" | xargs echo
# Sortie: a b c
Utilité : test et debug
# 1. Tester pipeline avant exécution
find . -name "*.tmp" | xargs
# Affiche: ./cache.tmp ./old.tmp ./test.tmp
# (au lieu de les supprimer)
# 2. Vérifier arguments
cat files.txt | xargs
# Montre ce qui serait passé en args
# 3. Formatter sortie
ls | xargs
# file1
# file2 → file1 file2 (sur 1 ligne)
# file3
Cas pratiques
# Concaténer lignes
cat list.txt | xargs
# line1
# line2 → line1 line2 line3
# line3
# Compter mots après filtre
grep "ERROR" logs.txt | cut -d: -f2 | xargs | wc -w
# Formater pour copier-coller
kubectl get pods -o name | xargs
# pod/app-1 pod/app-2 pod/app-3 (facile à copier)
Test avant destruction
# 1. Test avec xargs (echo)
find . -name "*.bak" | xargs
# ./file1.bak ./file2.bak
# 2. Vérification OK → exécuter
find . -name "*.bak" | xargs rm
Dry-run pattern
# Simuler commande
DRY_RUN=echo # ou vide pour exécution réelle
find . -name "*.log" | xargs $DRY_RUN rm
# Avec DRY_RUN=echo:
# rm file1.log file2.log (affiché, pas exécuté)
# Avec DRY_RUN="" :
# (exécution réelle)
DevOps examples
# Docker : lister IDs images
docker images -q | xargs
# abc123 def456 ghi789
# Git : liste fichiers modifiés sur 1 ligne
git ls-files -m | xargs
# file1.js file2.py README.md
# AWS : formatter instance IDs
aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' \
--output text | xargs
Astuce : xargs seul = meilleur dry-run avant commandes destructives.Option -r (--no-run-if-empty)
# Sans -r (exécute même si vide)
echo "" | xargs rm
# rm (exécute sans args → peut causer erreur)
# Avec -r (skip si vide)
echo "" | xargs -r rm
# (rien exécuté)
Problèmes sans -r
# Commandes qui échouent sans args
find /inexistant -name "*.log" | xargs rm
# rm: missing operand
# Avec -r (robuste)
find /inexistant -name "*.log" | xargs -r rm
# (skip silencieusement)
Scripts robustes
# ❌ Sans -r (peut échouer)
#!/bin/bash
find /backup -mtime +30 | xargs rm
# Si aucun fichier → erreur
# ✅ Avec -r (safe)
#!/bin/bash
find /backup -mtime +30 | xargs -r rm
# Si aucun fichier → continue
Exit codes
# Sans -r : exit code commande exécutée
echo "" | xargs rm; echo $?
# 1 (erreur rm)
# Avec -r : exit code 0 si skip
echo "" | xargs -r rm; echo $?
# 0 (pas d'erreur)
CI/CD patterns
# Docker cleanup (safe)
docker ps -q -f status=exited | xargs -r docker rm
# Si aucun container → OK
# Kubernetes delete pods
kubectl get pods -o name | grep Failed | xargs -r kubectl delete
# Si aucun pod Failed → continue
# Git cleanup branches
git branch --merged | grep -v "main" | xargs -r git branch -d
# Si aucune branch → OK
Pipelines conditionnels
# Nettoyer seulement si fichiers existent
find /tmp -name "*.tmp" -mtime +7 | xargs -r rm
# Backup seulement si fichiers modifiés
find /data -mtime -1 | xargs -r tar -czf backup.tar.gz
# Alert seulement si erreurs
grep ERROR /var/log/app.log | xargs -r -I {} echo "Alert: {}" | mail -s "Errors" admin@
Test existence
# Vérifier avant traiter
RESULT=$(find . -name "*.pdf")
if [ -n "$RESULT" ]; then
echo "$RESULT" | xargs process
fi
# Ou simplement
find . -name "*.pdf" | xargs -r process
Logging robuste
# Log seulement si fichiers
find /backup -type f | xargs -r -I {} echo "Found: {}" >> backup.log
# Avec count
COUNT=$(find . -name "*.log" | wc -l)
if [ $COUNT -gt 0 ]; then
echo "Processing $COUNT files"
find . -name "*.log" | xargs -r gzip
fi
Règle : Toujours -r dans scripts pour robustesse (pas d'erreur si entrée vide).Pattern cat | xargs
# Fichier liste.txt contient:
# /tmp/file1.log
# /tmp/file2.log
# /var/cache/old.tmp
cat liste.txt | xargs rm
Options robustes
# Avec gestion espaces
cat liste.txt | xargs -d '\n' rm
# Avec confirmation
cat liste.txt | xargs -p rm
# Avec verbose
cat liste.txt | xargs -t rm
# Combinaison safe
cat liste.txt | xargs -r -t -p rm
Formats fichier
# 1. Un fichier par ligne (standard)
/path/to/file1
/path/to/file2
cat list.txt | xargs rm
# 2. Multiples par ligne (séparés espaces)
file1 file2 file3
file4 file5
cat list.txt | xargs rm
# 3. Null-terminated
file1\0file2\0file3
cat list.txt | xargs -0 rm
Génération dynamique
# Créer liste puis traiter
find /var/log -name "*.log" -mtime +30 > old_logs.txt
# Review manually
cat old_logs.txt | xargs rm
# Ou combine
find . -name "*.tmp" | tee to_delete.txt | xargs rm
Cas DevOps
# Docker : remove images from list
cat docker_images_to_remove.txt | xargs docker rmi
# Kubernetes : delete resources
cat k8s_resources.txt | xargs kubectl delete
# resources.txt contient:
# pod/app-1
# pod/app-2
# service/old-svc
# Git : delete branches
cat branches_to_delete.txt | xargs -I {} git branch -D {}
# AWS : terminate instances
cat instance_ids.txt | xargs aws ec2 terminate-instances --instance-ids
Batch operations
# Télécharger URLs
cat urls.txt | xargs -n 1 -P 4 curl -O
# Copier fichiers
cat files_to_backup.txt | xargs -I {} cp {} /backup/
# Changer permissions
cat sensitive_files.txt | xargs chmod 600
# Recherche pattern
cat source_files.txt | xargs grep -l "TODO"
Filtrage avancé
# Ignore commentaires et vides
grep -v '^#' list.txt | grep -v '^$' | xargs rm
# Expansion variables
cat paths.txt | envsubst | xargs rm
# paths.txt: $HOME/tmp/cache
# Avec transformation
cat list.txt | sed 's/^/\/var\/log\//' | xargs rm
CI/CD manifests
# Deploy multiple manifests
cat k8s_manifests.txt | xargs -I {} kubectl apply -f {}
# manifests.txt:
# deployment.yaml
# service.yaml
# configmap.yaml
# Terraform modules
cat terraform_modules.txt | xargs -I {} terraform init {}
# Ansible playbooks
cat playbooks.txt | xargs -I {} ansible-playbook {}
Sécurité review
# 1. Générer liste
find . -name "*.old" > to_delete.txt
# 2. Review manuel
vim to_delete.txt
# 3. Exécuter avec confirmation
cat to_delete.txt | xargs -p rm
# 4. Ou dry-run first
cat to_delete.txt | xargs echo rm
Pattern : cat list.txt | xargs command = batch processing depuis fichier.Par défaut : séquentiel
# Sans -P : 1 commande à la fois
ls *.mp4 | xargs -I {} ffmpeg -i {} {}.webm
# Traite video1, puis video2, puis video3... (lent)
Option -P (parallel)
# Syntaxe
xargs -P NUM_PROCESSES command
# Exemples
ls *.mp4 | xargs -P 4 -I {} ffmpeg -i {} {}.webm
# 4 conversions simultanées
find . -name "*.jpg" | xargs -P 8 -I {} convert {} {}.png
# 8 conversions en parallèle
Déterminer nombre optimal
# Nombre CPU cores
NUM_CORES=$(nproc)
echo $NUM_CORES # Ex: 8
# CPU-bound : utiliser tous les cores
find . -name "*.jpg" | xargs -P $(nproc) -I {} convert {} {}.webm
# I/O-bound : 2-4x cores
find . -name "*.log" | xargs -P $(($(nproc) * 2)) gzip
# Network-bound : 10-50 selon bande passante
cat urls.txt | xargs -P 20 -n 1 curl -O
Performance comparison
# Benchmark : compresser 100 fichiers
# Séquentiel
time ls *.log | xargs gzip
# real: 2m30s
# Parallèle -P 4
time ls *.log | xargs -P 4 gzip
# real: 0m40s (3.75x plus rapide)
# Parallèle -P 8
time ls *.log | xargs -P 8 gzip
# real: 0m25s (6x plus rapide)
Cas DevOps
# Docker : build multiple images
cat Dockerfiles.txt | xargs -P 4 -I {} docker build -f {} .
# Kubernetes : check pods health
kubectl get pods -o name | xargs -P 10 -I {} kubectl exec {} -- curl -f localhost:8080/health
# Git : pull multiple repos
find ~/projects -name .git -type d | xargs -P 8 -I {} git -C {}/../ pull
# AWS : download S3 objects
aws s3 ls s3://bucket/ | awk '{print $4}' | xargs -P 16 -I {} aws s3 cp s3://bucket/{} ./
# Backup : compress logs
find /var/log -name "*.log" -mtime +7 | xargs -P $(nproc) gzip
Combinaison -P et -n
# 4 processus, 5 fichiers chacun
ls *.txt | xargs -P 4 -n 5 tar -czf batch.tar.gz
# Pattern efficace
find . -name "*.jpg" | xargs -P 8 -n 1 -I {} mogrify -resize 50% {}
# 8 processus, 1 image chacun
Monitoring progress
# Avec verbose
find . -name "*.mp4" | xargs -P 4 -t -I {} ffmpeg -i {} {}.webm
# Avec compteur
TOTAL=$(ls *.jpg | wc -l)
ls *.jpg | xargs -P 4 -I {} bash -c 'convert {} {}.png && echo "$((++COUNT))/$TOTAL"'
# Avec pv (progress bar)
find . -name "*.log" | pv -l -s $(find . -name "*.log" | wc -l) | xargs -P 8 gzip
Limites ressources
# Limiter CPU (avec nice)
find . -name "*.jpg" | xargs -P 4 -I {} nice -n 10 convert {} {}.png
# Limiter mémoire
find . -name "*.log" | xargs -P 2 -I {} bash -c 'ulimit -v 1000000 && gzip {}'
# Limiter I/O (ionice)
find /backup -type f | xargs -P 4 -I {} ionice -c 3 cp {} /archive/
-P 0 : illimité
# Autant de processus que d'items (DANGEREUX!)
ls *.txt | xargs -P 0 -I {} process {}
# Peut saturer système si trop de fichiers
Recommandation : -P $(nproc) pour CPU-bound, -P $((nproc*2)) pour I/O-bound.Limite système ARG_MAX
# Vérifier limite
getconf ARG_MAX
# Ex: 2097152 (2 Mo sur Linux moderne)
# Anciennes valeurs
# Linux ancien: 131072 (128 Ko)
# macOS: 262144 (256 Ko)
# Solaris: 1048576 (1 Mo)
Problème sans xargs
# ❌ ÉCHOUE si trop de fichiers
rm /var/log/*.log
# bash: /bin/rm: Argument list too long
# Calcul approximatif
# Si 10000 fichiers × 100 chars/nom = 1 Mo > limite
xargs contourne limite
# ✅ xargs découpe automatiquement
find /var/log -name "*.log" | xargs rm
# Exécute plusieurs fois rm avec batches
# rm file1 file2 ... file999
# rm file1000 file1001 ... file1999
# ...
Taille batch xargs
# xargs calcule taille optimale
xargs --show-limits < /dev/null
# Maximum length of command: 2097152
# Maximum parallelism: 1
# Size of command buffer: 2088960
# Forcer taille max args
xargs -s 4096 command # Max 4096 bytes par exec
Test limite
# Générer beaucoup fichiers
seq 1 100000 | xargs -I {} touch file_{}
# ❌ Échoue sans xargs
ls file_* | wc -l # OK
rm file_* # Erreur: Argument list too long
# ✅ OK avec xargs
ls file_* | xargs rm # Fonctionne
# Ou mieux
find . -name "file_*" -delete
Cas problématiques
# Gros répertoires
ls /var/log/archive/*.gz # Peut échouer
find /var/log/archive -name "*.gz" | xargs ls -lh # OK
# Wildcards multiples
grep pattern *.txt *.md *.log # Risque limite
find . -name "*.txt" -o -name "*.md" | xargs grep pattern # Sûr
Solutions alternatives
# 1. find -exec (toujours safe)
find . -name "*.tmp" -exec rm {} +
# 2. find -delete (pour rm)
find . -name "*.tmp" -delete
# 3. while read loop (lent mais sûr)
find . -name "*.log" | while read file; do rm "$file"; done
# 4. xargs (rapide et sûr)
find . -name "*.log" | xargs rm
DevOps scale
# Docker : millions images
docker images -q | xargs -n 100 docker rmi
# Batch de 100 pour éviter limite
# Kubernetes : masse pods
kubectl get pods -A -o name | xargs -n 50 kubectl delete
# Logs : des milliers fichiers
find /var/log -type f -mtime +365 | xargs -n 1000 rm
# Git : gros monorepo
git ls-files | xargs -n 500 git add
Calcul sécurité
# Vérifier avant exécution
ARG_MAX=$(getconf ARG_MAX)
FILE_COUNT=$(find . -name "*.log" | wc -l)
AVG_LENGTH=100 # chars moyen nom fichier
TOTAL_SIZE=$((FILE_COUNT * AVG_LENGTH))
if [ $TOTAL_SIZE -gt $ARG_MAX ]; then
echo "Utiliser xargs obligatoire"
find . -name "*.log" | xargs rm
else
rm *.log
fi
Règle : Toujours xargs pour opérations massives (évite "Argument list too long").Pattern find + xargs + grep
# Syntaxe de base
find [path] [tests] | xargs grep [options] "pattern"
# Exemple simple
find . -name "*.txt" | xargs grep "ERROR"
# Avec numéros lignes
find . -name "*.log" | xargs grep -n "error"
# Insensible casse
find . -type f | xargs grep -i "todo"
Gestion espaces noms
# ❌ Sans -0 (peut échouer)
find . -name "*.txt" | xargs grep "pattern"
# ✅ Avec -0 (robuste)
find . -name "*.txt" -print0 | xargs -0 grep "pattern"
Options grep utiles
# Fichiers contenant pattern
find . -name "*.py" | xargs grep -l "import requests"
# Fichiers NE contenant PAS
find . -name "*.js" | xargs grep -L "use strict"
# Compter occurrences
find . -name "*.log" | xargs grep -c "ERROR" | grep -v :0
# Contexte (lignes avant/après)
find . -name "*.conf" | xargs grep -A 3 -B 3 "database"
Cas DevOps
# Logs : chercher erreurs
find /var/log -name "*.log" -mtime -7 -print0 | \
xargs -0 grep -h "ERROR\|FATAL" | sort | uniq -c
# Code : dépendances obsolètes
find . -name "package.json" | xargs grep -l "lodash.*3\."
# Configs : mots de passe hardcodés (audit)
find . -name "*.yml" -o -name "*.yaml" | xargs grep -i "password.*="
# Docker : images vulnérables
find . -name "Dockerfile" | xargs grep -l "FROM.*:latest"
# Kubernetes : ressources sans limits
find k8s/ -name "*.yaml" | xargs grep -L "resources.limits"
Multi-patterns
# Plusieurs patterns (OR)
find . -name "*.log" | xargs grep -E "ERROR|WARN|FATAL"
# Exclusion pattern
find . -name "*.txt" | xargs grep "TODO" | grep -v "# TODO (ok)"
# Pattern complexe
find . -type f | xargs grep -P '\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b' -i
# (emails)
Performance
# Paralléliser recherche
find . -name "*.log" -print0 | xargs -0 -P 4 grep "ERROR"
# Limiter fichiers traités
find . -name "*.txt" -print0 | xargs -0 -n 50 grep "pattern"
Alternatives
# 1. grep récursif (simple)
grep -r "pattern" .
# 2. find -exec (sûr)
find . -name "*.txt" -exec grep "pattern" {} +
# 3. ripgrep (très rapide)
rg "pattern" --type txt
# 4. xargs (flexible)
find . -name "*.txt" | xargs grep "pattern"
Extraction résultats
# Fichiers + lignes
find . -name "*.py" | xargs grep -Hn "def main" > functions.txt
# Seulement noms fichiers
find . -name "*.sh" | xargs grep -l "#!/bin/bash" > bash_scripts.txt
# Statistiques
find . -name "*.log" | xargs grep "ERROR" | \
awk '{print $1}' | sort | uniq -c | sort -rn
Git integration
# Chercher dans fichiers trackés
git ls-files | xargs grep "FIXME"
# Fichiers modifiés avec pattern
git diff --name-only | xargs grep "console.log"
# Multi-repos
find ~/projects -name .git -type d | \
xargs -I {} bash -c 'cd {}/../ && git grep "deprecated"'
Pattern : find | xargs grep = recherche massive sélective et rapide.Erreurs courantes
| Erreur | Problème | Solution |
|---|---|---|
| Espaces noms | find | xargs casse fichiers |
-print0 | xargs -0 |
| Commandes destructives | xargs rm sans test |
-p ou -t ou echo test |
| Entrée vide | Erreur si aucun fichier | xargs -r |
| Quotes/spéciaux | Caractères interprétés | -0 + proper quoting |
| Race conditions | Fichiers changés pendant exec | Snapshots ou locks |
| Ressources | Trop de processus -P |
Limiter selon CPU |
Checklist sécurité
# ✅ 1. Toujours tester avec echo
find . -name "*.tmp" | xargs echo rm
# Vérifier output avant exécuter
# ✅ 2. Utiliser -0 avec find
find . -name "*.log" -print0 | xargs -0 command
# ✅ 3. Confirmation (-p) pour destructif
find . -name "*.bak" | xargs -p rm
# ✅ 4. Verbose (-t) pour audit
find . -type f | xargs -t chmod 644 2>> audit.log
# ✅ 5. No-run-if-empty (-r)
find /inexistant -name "*.log" | xargs -r rm
Commandes dangereuses
# ❌ DANGEREUX
find / | xargs rm # Peut tout supprimer!
find . | xargs chmod 777 # Permissions ouvertes
find . -name "*.sh" | xargs rm # Peut casser scripts actifs
# ✅ SÉCURISÉ
find /tmp -name "*.tmp" -mtime +7 | xargs -r -p rm
find . -type f -name "*.txt" | xargs -0 chmod 644
find . -name "*.bak" | xargs -t rm 2>&1 | tee cleanup.log
Gestion erreurs
# Continuer sur erreur
find . -name "*.log" | xargs -r gzip || echo "Some failed"
# Capturer sorties
find . -name "*.txt" | xargs grep "pattern" 2>errors.log 1>results.log
# Exit on error
set -e
find . -name "*.conf" | xargs -r validate_config
Caractères spéciaux
# Fichiers avec quotes, $, etc.
touch "file with 'quotes'.txt"
touch "file_with_$VAR.txt"
# ❌ Échoue
find . -name "*.txt" | xargs cat
# ✅ Fonctionne
find . -name "*.txt" -print0 | xargs -0 cat
Limites ressources
# Limiter mémoire
find . -name "*.log" | xargs -n 100 -P 2 gzip
# Max 100 fichiers par process, 2 processus max
# Limiter CPU
find . -name "*.jpg" | xargs -P 4 -I {} nice -n 10 convert {} {}.png
# Timeout par commande
find . -name "*.mp4" | xargs -I {} timeout 60s ffmpeg -i {} {}.webm
Best practices DevOps
# 1. Dry-run systematique
DRY_RUN=echo # ou vide
find . -name "*.old" | xargs $DRY_RUN rm
# 2. Logging
find . -name "*.log" | xargs -t gzip 2>&1 | tee -a compress.log
# 3. Monitoring
START=$(date +%s)
find . -name "*.tmp" | xargs -r rm
END=$(date +%s)
echo "Cleanup took $((END-START))s" >> metrics.log
# 4. Alerting
ERRORS=$(find /data -name "*.corrupted" | wc -l)
if [ $ERRORS -gt 0 ]; then
find /data -name "*.corrupted" | xargs -I {} echo "Corrupted: {}" | \
mail -s "Data Alert" admin@
fi
Code review checklist
-
-print0 | xargs -0avec find -
-rsi entrée peut être vide -
-pou-tpour commandes destructives - Test avec
echoavant exécution réelle -
-Plimité selon ressources disponibles - Gestion erreurs (exit codes, logs)
- Pas de wildcard direct (
rm *) - Paths absolus quand nécessaire
echo avant exécution destructive.