boucle avec des nom de fichier avec espace [Shell] - Shell/Batch - Programmation
Marsh Posté le 03-06-2008 à 19:51:06
Sauf que le probleme n'est pas sur la ligne 1, mais sur le reste, que tu ne nous a pas détaillé.
A+,
Marsh Posté le 04-06-2008 à 09:24:29
Si, il y a déjà un problème sur la ligne 1 : il faut qu'il mette des double quotes autour du `ls`, sinon i prendra successivement le nom de chacun des composants de chaque nom de fichier contenant des espaces.
Ensuite suivant ce qu'il fait dans la boucle il faudra éventuellement également qu'il mettre des double quotes autour de $i.
for i in "`ls`" |
Marsh Posté le 04-06-2008 à 15:13:46
matafan a écrit : Si, il y a déjà un problème sur la ligne 1 : il faut qu'il mette des double quotes autour du `ls`, sinon i prendra successivement le nom de chacun des composants de chaque nom de fichier contenant des espaces.
|
Le fait de mettre des guillemets autour du ls ne changera rien. Ou dans le meilleur des cas il prendra l'ensemble de tous les noms comme un seul argument. Mais mettre des guillemets à "$i" est une excellente idée.
Puisque le problème vient du for (qui utilise l'espace pour séparer ses éléments), ben faut s'en affranchir. Le read est tout indiqué pour ça puisque lui se cale sur le <return> et que toute ligne (même venant d'une commande) se termine par un <return>...
Code :
|
Petit inconvénient => qui dit pipe dit sous processus. Et donc on ne pourra faire ressortir aucune variable de la boucle. Si ce point ne présente pas de soucis alors c'est bon. Sinon on peut gruger un petit peu en utilisant des parenthèses
Code :
|
Mais cela ne fait que reporter le problème. Si vraiment on veut s'en affranchir totalement, on ne peut plus utiliser le pipe donc faut passer par un fichier temporaire
Code :
|
Cette solution évite les problèmes mentionnés précédement mais on entre dans une autre problématique concernant les accès multiples sur le même fichier (si le script est lancé deux fois en parallèle => dommage pour "fichier_temporaire" ) qui ne peut se régler que par la création d'un fichier temporaire au nom unique (en incluant par exemple dans son nom la variable "$$" => n° process)
Comme quoi, en partant d'un problème tout con, si on veut tout gérer on peut arriver à des sacrés soucis...
Marsh Posté le 04-06-2008 à 15:35:11
Sve@r a écrit : Le fait de mettre des guillemets autour du ls ne changera rien. Ou dans le meilleur des cas il prendra l'ensemble de tous les noms comme un seul argument. |
C'est faux. Tu te t'en serait rendu compte si comme moi tu avais essayé
Pour info l'explication est dans le man de bash :
Citation : Command Substitution |
S'il fait comme j'ai indiqué, ça marchera.
Marsh Posté le 04-06-2008 à 15:37:52
Citation : Le fait de mettre des guillemets autour du ls ne changera rien. Ou dans le meilleur des cas il prendra l'ensemble de tous les noms comme un seul argument. Mais mettre des guillemets à "$i" est une excellente idée. |
Avec un `ls -Q` on ne recupere pas le nom entre double quotes?. Bon, il y a peut être des options a mettre en plus pour n'avoir que le nom du fichier.
A+,
Marsh Posté le 04-06-2008 à 15:41:08
matafan a écrit :
|
L'explication en question dit qu'il doit prendre tous les noms comme un seul argument, non?
A+,
Marsh Posté le 04-06-2008 à 18:36:10
Excusé moi de ne pas avoir été assez clair. Je voulais récupérer chaque nom de fichier .
Merci beaucoup Sve@r c'est ce que je cherchais !
Marsh Posté le 04-06-2008 à 21:47:36
Bon j'ai fumé pour le "`ls`", effectivement ça renvoit tout comme un mot.
La solution la plus simple c'est quand même "for i in *" ...
Marsh Posté le 05-06-2008 à 21:31:12
matafan a écrit : Bon j'ai fumé pour le "`ls`", effectivement ça renvoit tout comme un mot. |
Non t'as pas fumé. Auourd'hui j'ai essayé cette syntaxe sur un bash de Fedora Core 7 et effectivement ça marche.
Cependant, travaillant dans un milieu hétérogène (avec du sun, du Redhat, du Ubuntu) et étonné de ce résultat qui ne correspondait pas à ce que j'attendais, j'ai testé sur un bash de Solaris puis un ksh => dans les deux cas cela redonne ce que j'avais prévu => un seul mot.
Donc il est probable que cette syntaxe devienne un standard dans le futur mais cela ne l'est pas actuellement et celui qui veut faire un script "portable descendant" ne peut pas l'utiliser.
Sinon l'option "ls -Q" de Gilou fonctionne aussi sur FC7 mais pas sur Solaris. Là aussi pas standard.
Marsh Posté le 06-06-2008 à 04:00:20
Oui, ls -Q c'est pas Posix, donc pas OSXien, par contre ca a l'air d'être Gnuesque et Linuxien.
A+,
Marsh Posté le 23-11-2009 à 14:56:39
Je déterre le sujet pour ceux qui passent et ont le même soucis (on le rencontre assez souvent quand même) une solution assez simple existe:
Code :
|
NB: Si on utilise rien d'autre qui a besoin d'IFS sauvegarder sa valeur n'est même pas obligatoire car une fois le script fini il reprend sa valeur normale.
Marsh Posté le 23-03-2012 à 16:37:25
Merci de l'avoir sorti des oubliettes HDDSYonex.
Ca marche nikel
Marsh Posté le 23-03-2012 à 18:42:16
Tu peux aussi bêtement protéger, t'es pas obligé de changer IFS c'est un peu bourrin
for i in "$(ls)"; do |
Marsh Posté le 25-03-2012 à 16:48:31
salut,
et si tout simplement vous utilisiez les possibilités du shell : le développement des chemins
Code :
|
Marsh Posté le 03-06-2008 à 18:52:26
Salut,
Je souhaiterai faire :
Le problème est que si le répertoire contient des fichiers, ayant des espaces dans leur nom, sa ne marche pas