find . -name "filename including space" -print0 | xargs -0 ls -aldF > log.txt
find . -name "filename including space" -print0 | xargs -0 rm -rdf
Est-il possible de combiner ces deux commandes en une seule pour qu'une seule recherche soit effectuée au lieu de 2?
Je sais que pour xargs -I il peut y avoir des moyens de le faire, ce qui peut conduire à des erreurs lors de la poursuite des noms de fichiers, y compris les espaces. Tout conseil est très apprécié.
Si vous voulez simplement éviter de faire plusieurs fois le find
, vous pouvez faire un tee
juste après le find
, en enregistrant la sortie find
dans un fichier, puis exécutez les lignes comme:
find . -name "filename including space" -print0 | tee my_teed_file | xargs -0 ls -aldF > log.txt
cat my_teed_file | xargs -0 rm -rdf
Une autre façon d'accomplir cette même chose (si c'est vraiment ce que vous voulez accomplir) est de stocker la sortie du find
dans une variable (en supposant que ce n'est pas TB de données):
founddata=`find . -name "filename including space" -print0`
echo "$founddata" | xargs -0 ls -aldF > log.txt
echo "$founddata" | xargs -0 rm -rdf
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt; rm -rdf {}'
Je crois que toutes ces réponses ont désormais permis de résoudre ce problème. Et j'ai essayé les 2 solutions de Jonathan et la voie de Glenn, qui fonctionnaient toutes très bien sur mon Mac OS X. La méthode de mouviciel n'a pas fonctionné sur mon OS peut-être pour des raisons de configuration. Et je pense que c'est similaire à la deuxième méthode de Jonathan (je peux me tromper).
Comme mentionné dans les commentaires sur la méthode de Glenn, un petit ajustement est nécessaire. Voici donc la commande que j'ai essayée qui fonctionnait parfaitement pour info:
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} | tee -a log.txt ; rm -rdf {}'
Ou mieux comme suggéré par Glenn:
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt ; rm -rdf {}'
Tant que vous n'avez pas de nouvelle ligne dans vos noms de fichiers, vous n'avez pas besoin de -print0 pour GNU Parallel:
find . -name "My brother's 12\" records" | parallel ls {}\; rm -rdf {} >log.txt
Regardez la vidéo d'introduction pour en savoir plus: http://www.youtube.com/watch?v=OpaiGYxkSuQ
Juste une variation de l'approche xargs
sans cette horrible -print0
et xargs -0
, voici comment je procéderais:
ls -1 *.txt | xargs --delimiter "\n" --max-args 1 --replace={} sh -c 'cat {}; echo "\n"'
Notes de bas de page:
xargs
mais pour la compréhension du lecteur, j'ai utilisé les longues.ls -1
quand je veux un comportement non récursif plutôt que find -maxdepth 1 -iname "*.txt"
qui est un peu plus verbeux.Je suis en retard à la fête, mais il y a une autre solution qui n'a pas été abordée ici: les fonctions définies par l'utilisateur. Mettre plusieurs instructions sur une seule ligne est compliqué et peut être difficile à lire/à maintenir. La boucle for ci-dessus évite cela, mais il est possible de dépasser la longueur de la ligne de commande.
Voici une autre façon (non testée).
function processFiles {
ls -aldF "$@"
rm -rdf "$@"
}
export -f processFiles
find . -name "filename including space"` -print0 \
| xargs -0 bash -c processFiles dummyArg > log.txt
C'est assez simple, sauf pour le "dummyArg" qui m'a donné beaucoup de chagrin. Lorsque vous exécutez bash de cette manière, les arguments sont lus dans
"$0" "$1" "$2" ....
au lieu de l'attendu
"$1" "$2" "$3" ....
Puisque processFiles {} s'attend à ce que le premier argument soit "$ 1", nous devons insérer une valeur fictive dans "$ 0".
Footnontes:
Vous pouvez exécuter plusieurs commandes après find
en utilisant for
au lieu de xargs
:
IFS=$'\n'
for F in `find . -name "filename including space"`
do
ls -aldF $F > log.txt
rm -rdf $F
done
IFS
définit le séparateur de champ interne, qui est par défaut <space><tab> <newline>. Si vos noms de fichiers peuvent contenir des espaces, il est préférable de les redéfinir comme ci-dessus.
Une autre solution:
find . -name "filename including space" -print0 \
| xargs -0 -I FOUND echo "$(ls -aldF FOUND > log.txt ; rm -rdf FOUND)"