Tout d'abord, n'utilisez pas la ls
sortie comme liste de fichiers . Utilisez l'extension shell ou find
. Voir ci-dessous pour les conséquences potentielles d'une mauvaise utilisation de ls + xargs et un exemple d' xargs
utilisation appropriée .
1. Manière simple: pour la boucle
Si vous souhaitez traiter uniquement les fichiers ci-dessous A/
, une simple for
boucle devrait suffire:
for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1 Pourquoi pas ls | xargs
?
Voici un exemple de la façon dont les choses peuvent mal tourner si vous utilisez ls
avec xargs
pour le travail. Considérez un scénario suivant:
commençons par créer des fichiers vides:
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
$ touch A/mypreciousfile.dat
$ touch A/mypreciousfile.dat.ans
voir les fichiers et qu'ils ne contiennent rien:
$ ls -1 A/
mypreciousfile.dat
mypreciousfile.dat with junk at the end.dat
mypreciousfile.dat.ans
$ cat A/*
exécutez une commande magique en utilisant xargs
:
$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
le résultat:
$ cat A/mypreciousfile.dat
TRICKED with junk at the end.dat.ans
$ cat A/mypreciousfile.dat.ans
TRICKED
Vous venez donc de remplacer les deux mypreciousfile.dat
et mypreciousfile.dat.ans
. S'il y avait du contenu dans ces fichiers, il aurait été effacé.
2. Utilisation xargs
: la bonne façon avec find
Si vous souhaitez insister sur l'utilisation xargs
, utilisez -0
(noms à terminaison nulle):
find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
Remarquez deux choses:
- de cette façon, vous créerez des fichiers avec une
.dat.ans
fin;
- cela se cassera si un nom de fichier contient un signe de citation (
"
).
Les deux problèmes peuvent être résolus par différentes méthodes d'appel du shell:
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3. Tout est fait en dedans find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
Encore une fois, cela produit des .dat.ans
fichiers et se cassera si les noms de fichiers contiennent "
. Pour ce faire, utilisez bash
et modifiez la façon dont elle est invoquée:
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;