Tout d'abord, n'utilisez pas la lssortie 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' xargsutilisation appropriée .
1. Manière simple: pour la boucle
Si vous souhaitez traiter uniquement les fichiers ci-dessous A/, une simple forboucle 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 lsavec xargspour 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.datet 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.ansfin;
- 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.ansfichiers et se cassera si les noms de fichiers contiennent ". Pour ce faire, utilisez bashet modifiez la façon dont elle est invoquée:
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;