Bonjour
Ce code coupe les fichiers au niveau des espaces dans les noms :
si je fais :
for fichier in $(find * -maxdepth 0 -prune -type f )
IFS='
'
for fichier in $(find * -maxdepth 0 -prune -type f ) ça fonctionne.
J'aimerais savoir s'il n'y a pas un autres moyen que le changement de l'ISF pour faire marcher cette ligne.
Merci
# -print0 ?
Posté par gaaaaaAab . Évalué à 3.
j'ai l'impression de manquer un peu de contexte pour savoir si je ne réponds pas à côté de la plaque, mais find dispose de l'option print0 qui permet de séparer les objets trouvés par le caractère nul plutôt que l'espace. Il faut du coup utiliser quelque chose qui sait se débrouiller avec des éléments séparés par des caractères nuls plutôt que des espaces (souvent, c'est xargs avec l'option -0).
Difficile d'en dire plus sans savoir comment ça s'intègre dans ce que tu essaies de faire.
# Plusieurs solutions
Posté par liberforce (site web personnel) . Évalué à 5. Dernière modification le 02 octobre 2019 à 18:11.
Souvent la méthode avec xargs est mieux (un seul processus lancé), sauf dans le cas où tu as beaucoup de fichiers et tu risques de dépasser la liste d'arguments maximale qu'on peut passer à un process.
Autre liste de méthodes ici:
https://stackoverflow.com/questions/9612090/how-to-loop-through-file-names-returned-by-find
Je note sur leur réponse que tu peux te passer de find en utilisant
shopt -s globstar
et glober en récursif avec**/*
.[^] # Re: Plusieurs solutions
Posté par adecot . Évalué à 1.
Bonjour
Désolé de répondre un peu tard. Merci pour ces différentes solutions qui fonctionnent parfaitement dans mon cas.
[^] # Re: Plusieurs solutions
Posté par adecot . Évalué à 1. Dernière modification le 05 octobre 2019 à 10:58.
Re :
Si je fais par exemple
ça me donne bien la liste souhaité, mais le "fin de ligne ne s'affiche qu'une fois à la fin de la liste alors qu'il se trouve bien dans la boucle 'for'. Problème de syntaxe ?
[^] # Re: Plusieurs solutions
Posté par Cyril Brulebois (site web personnel) . Évalué à 1.
La boucle n'est pas bonne, il suffit d'ajouter un peu de texte autour de
$f
pour s'en convaincre :Normal : le résultat de
find
est encadré par des guillemets,for
opère sur un seul mot, donc un seul tour de boucle.Au passage, je ne comprends pas à quoi sert
find *
plutôt quefind
. Cela va même provoquer une erreur quand un répertoire est vide, puisque*
ne sera pas remplacé, doncfind
va essayer de travailler sur (littéralement)*
…Debian Consultant @ DEBAMAX
[^] # Re: Plusieurs solutions
Posté par liberforce (site web personnel) . Évalué à 2. Dernière modification le 07 octobre 2019 à 16:14.
Ah, effectivement, mea culpa. Mais on ne peut pas non plus enlever les guillemets autour du
$(find ...)
car alors on ne gère plus les fichiers ayant un espace dans leur nom.[^] # Re: Plusieurs solutions
Posté par Cyril Brulebois (site web personnel) . Évalué à 1. Dernière modification le 07 octobre 2019 à 18:46.
C'est donc une mauvaise solution, puisque cela met en place une boucle qui ne fait qu'un seul tour de boucle avec comme seul objet la concaténation de l'ensemble de la sortie de
find
, non ?Debian Consultant @ DEBAMAX
[^] # Re: Plusieurs solutions
Posté par liberforce (site web personnel) . Évalué à 2.
Je pense que c'est une solution qui reste possible, mais pas sans changer l'IFS, ce que l'OP ne souhaite pas.
# Autres solutions
Posté par AncalagonTotof . Évalué à 1.
Attention, j'écris ça de tête, sans vérifier.
D'abord, une solution simple mais bourrin et pas sans poser problème :
Le problème ? Si une variable est initialisée hors de la boucle, elle ne peut pas être modifiée dans cette boucle :
affichera 1, quelque soit le nombre de tour de boucle, car le while est à droite d'un pipe ('|'), et s'exécute donc dans un shell fils.
Pour que le while reste dans le même shell, et toujours en étant bourrin :
Cette fois, v va changer en fonction du nombre de lignes dans le fichier temporaire.
Pour éviter ce fichier temporaire, il faut utiliser quelque chose du genre :
C'est surtout ici que j'ai un doute sur la syntaxe. Mais si erreur il y a, on a l'idée.
[^] # Re: Autres solutions
Posté par AncalagonTotof . Évalué à 1.
[Complément 1]
Toutes ces formes d'écriture pallient au problème du
for
. Lefor
reçoit les paramètres après interprétation par le shell, et si ces paramètres comportent des espaces, ils deviennent deux ou plusieurs paramètres dufor
.[Complément 2]
La version avec fichier temporaire présente l'inconvénient du … fichier temporaire ! Mais, dans certains cas, le résultat du
find
peut être utile à plusieurs boucle indépendantes, et donc, ce fichier temporaire permet d'exécuter cefind
une fois pour toutes# re : problème supplémentaire
Posté par adecot . Évalué à 1.
Merci pour les différentes solutions mais du coup j'ai un problème supplémentaire :
Si je fais par exemple
j'obtiens bien la liste souhaité, mais le "fin de ligne ne s'affiche qu'une fois à la fin de la liste alors qu'il se trouve bien dans la boucle 'for'. Problème de syntaxe ?
[^] # Re: re : problème supplémentaire
Posté par AncalagonTotof . Évalué à 1. Dernière modification le 06 octobre 2019 à 12:19.
[oh, ma réponse d'hier n'est pas passée ? Je la refais]
Oui, c'est tout à fait normal.
L'expression
$(find * -maxdepth 0 -type f)
est entre guillemets, et de ce fait, elle constitue un et un seul paramètre dufor
.f
prend donc une et une seule valeur, d'où un seul tour de boucle et un seul message "fin de ligne".Problème : si tu supprimes les guillemets, tu retombes sur le problèmes espaces dans les noms de fichier. Chaque espace divisera le nom en deux et créera un paramètre supplémentaire au
for
là où il ne faudrait pas.On en revient aux solutions à base de
read
et dewhile
.Pourquoi s'acharner sur le
for
sinon ? Je ne l'utilise quasiment jamais, cette limitation est trop contraignante.[^] # Re: re : problème supplémentaire
Posté par Cyril Brulebois (site web personnel) . Évalué à 1.
Note, le commentaire est en doublon de celui-ci, posté quelques minutes avant, qui apporte déjà des réponses…
→ https://linuxfr.org/nodes/118246/comments/1785596
Debian Consultant @ DEBAMAX
[^] # Re: re : problème supplémentaire
Posté par AncalagonTotof . Évalué à 1.
Ah OK, j'avais pas vu la feinte !
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.