Votre navigateur est obsolète. Téléchargez un navigateur moderne, par exemple FireFox.
Léa-Linux : Forum
Le forum de Léa abrite des discussions autour des Logiciels libres.
Syndication
  • RSS ForumForum complet
  • RSS Forum - DéveloppementForum - Développement
  • RSS Forum - Développement - 305283Cette discussion

Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Important : quand vous posez une question, n'oubliez pas de nous donner les indications suffisantes pour que nous puissions répondre. En effet, la divination n'est pas le fort du Linuxien averti. Pour une meilleure compréhension, le bon usage de la grammaire et de l'orthographe est fortement encouragé. En particulier, le langage SMS est à éviter absolument. En cas d'abus, il pourra être censuré sans autre forme de procès.
Les messages dont le contenu est illégal (incitant à la haine - raciale ou autre, diffamant), ou dont le contenu est sans rapport avec le sujet du forum, ou qui sont parfaitement stupides ou hors sujet seront supprimés sans pitié. Il pourra même être fait appel au fournisseur d'accès du coupable pour faire cesser ses agissements.
» Index du forum » Développement » Lister les dossiers avec un for
Aller à la discussion: PrécédentSuivante
Action: Nouveau sujetChercherS'authentifier
Aller page:  12Suivante
Page courante:1 sur 2
Lister les dossiers avec un for
Auteur: Franckinux (IP enregistrée)
Date: le 24 septembre 2006 à 16:44

Bonjour,

Voilà je suis en train d'essayer de faire un script qui liste tous les dossiers et uniquement les dossiers contenus dans un dossier parent (.temp) :

for i in `find $CIBLE_NAME/.temp -type d`
do
    echo "$i"
done


mon problème : cela ne fonctionne pas correctement avec les noms de dossiers qui ont un espace : chaque mot composant le nom du dossier dans $i est vu comme un dossier.

si quelqu'un peut me donner un coup de main...

merci d'avance image : content

Re: Lister les dossiers avec un for
Auteur: Basile STARYNKEVITCH (IP enregistrée)
Date: le 24 septembre 2006 à 16:45

Pas besoin d'un for ici
find $CIBLE_NAME/.temp -type d -print



----

Basile STARYNKEVITCH où on trouve mon mél

Membre de l'APRIL « promouvoir et défendre le logiciel libre » - adhérez vous aussi à l'APRIL!

N.B. N'hesitez pas à consulter aussi mes contributions antérieures.

Re: Lister les dossiers avec un for
Auteur: Franckinux (IP enregistrée)
Date: le 24 septembre 2006 à 16:59

merci pour ta réponse.

heu si parce qu'en fait là ou il y a echo "$i" je veux faire un traitement particulier pour chaque dossier...

Re: Lister les dossiers avec un for
Auteur: Basile STARYNKEVITCH (IP enregistrée)
Date: le 24 septembre 2006 à 17:03

Alors fais un script tonscript pour ce traitement particulier, puis
find $CIBLE/.temp -type d -exec tonscript '{}' ';'


Et sinon, sous zsh, plus simplement
for f in $CIBLE/.temp/**/*(/); do tonscript $f; done


Enfin, un langage comme Ruby, Ocaml ou Perl pourrait peut-être convenir mieux à ton traitement.

----

Basile STARYNKEVITCH où on trouve mon mél

Membre de l'APRIL « promouvoir et défendre le logiciel libre » - adhérez vous aussi à l'APRIL!

N.B. N'hesitez pas à consulter aussi mes contributions antérieures.

Re: Lister les dossiers avec un for
Avatar
Auteur: Franckinux (IP enregistrée)
Date: le 24 septembre 2006 à 17:08

ok merci image : content

Re: Lister les dossiers avec un for
Avatar
Auteur: nicola (IP enregistrée)
Date: le 24 septembre 2006 à 17:20

Tu peux aussi tester si i est un répertoire avec if [ -d $i ] then fi.

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Re: Lister les dossiers avec un for
Avatar
Auteur: Franckinux (IP enregistrée)
Date: le 24 septembre 2006 à 17:34

oui mais il le sera que si il est composé d'un seul mot, et moi ce que je voulais c'est lire la totalité du nom du répertoire.
ex : si j'ai un dossier nommé : mon dossier numero 1
echo $i trouve 4 dossiers sui sont :
mon
dossier
numero
1

donc if [ -d $i ] then fi ne trouvera jamais le dossier en question...

Re: Lister les dossiers avec un for
Auteur: Basile STARYNKEVITCH (IP enregistrée)
Date: le 24 septembre 2006 à 17:39

Alors faire
if [-d "$i" ]; then ...


Celà étant, c'est une mauvaise idée d'avoir des noms de fichiers ou de repertoires avec des blancs; il faut préférer le blanc souligné.

----

Basile STARYNKEVITCH où on trouve mon mél

Membre de l'APRIL « promouvoir et défendre le logiciel libre » - adhérez vous aussi à l'APRIL!

N.B. N'hesitez pas à consulter aussi mes contributions antérieures.

Re: Lister les dossiers avec un for
Avatar
Auteur: Sve@r (IP enregistrée)
Date: le 24 septembre 2006 à 17:59

Franckinux a écrit :

mon problème : cela ne fonctionne pas correctement
avec les noms de dossiers qui ont un espace :
chaque mot composant le nom du dossier dans $i est
vu comme un dossier.

D'une façon générale, la syntaxe "for i in `commande`" est plutôt mauvaise car ce problème peut se retrouver à chaque fois si la commande renvoie des mots avec espace.
Il vaut mieux privilégier la syntaxe
#!/bin/sh
commande |while read i
do
...<traitement de "$i">
done

Comme le "read" utilise le "return" pour valider la saisie, on est certain que "$i" contiendra toujours l'ensemble de chaque ligne renvoyée par "commande" - Seul inconvénient: si on remplit une variable dans le "do" (donc dans le processus fils issu du pipe), on la perd en fin de "done" car on est revenu dans le processus père. On peut éviter le problème en utilisant la structure
#!/bin/sh
# On crée un fichier contenant le résultat
commande >fichier

# On crée un nouveau canal IO contenant le fichier
exec 3<fichier

# On lit ce canal
while read i 0<&3
do
...<traitement de "$i">
done


Là, c'est bon mais faut faire gaffe à l'environnement multi utilisateurs multi tâches => que se passe-t-il si le même script est lancé par plusieurs personnes en même temps ou plusiers fois en parallèles par la même personne => risque d'écrasement multiple de "fichier" => faut lui inclure "$$" dans son nom pour que son nom devienne unique (et accessoirement, il vaut mieux le placer dans "/tmp" qui a pour rôle d'héberger les fichiers temporaires)

#!/bin/sh
# On crée un fichier avec nom unique
commande >/tmp/fichier$$

# On crée un nouveau canal IO contenant le fichier
exec 3</tmp/fichier$$

# On lit ce canal
while read i 0<&3
do
...<traitement de "$i">
done


Et comme l'a dit Basile, faut toujours encadrer "$i" par des guillemets chaque fois qu'on va l'utiliser pour que l'espace éventuel soit intégré dans la chaîne correspondante...

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Re: Lister les dossiers avec un for
Avatar
Auteur: Franckinux (IP enregistrée)
Date: le 24 septembre 2006 à 19:21

Basile :
oui mais ça ne change rien au problème : dans le cas ou il y a des espaces dans le nom du dossier, dans $i ou "$i" on n'a que des morceaux...
effectivement il faudrait des noms sans espaces, mais tout changer concerne pas mal de dossiers, et puis en mettant des \ ou des "" on arrive à bosser sur des noms avec espaces...

Sve@r:
merci pour les détails, ça devient complexe !
au début j'ai essayé avec while .. read et ça marchait super...

while read i
do
...<traitement de "$i">
done < liste.txt


mais le problème qu'il y avait c'est que je voulais aussi utiliser un read pour confirmer ou non d'exécuter le traitement :

ls /bidule > liste.txt

while read i
do
   ...<echo détails du traitement de "$i">
   echo "Faire vraiment traitement de $i ? (oui/non)" read val
   if[ $val = "oui" ]; then
       ...<traitement de "$i">
   fi
done < liste.txt


et un read dans un read ça ne fonctionne pas : le script ne me demande pas la confirmation...

en fait j'aimerais mettre en place un truc simple...si possible sinon effectivement je pourrais utiliser les autres solutions.

Re: Lister les dossiers avec un for
Avatar
Auteur: Sve@r (IP enregistrée)
Date: le 24 septembre 2006 à 19:53

Franckinux a écrit :

merci pour les détails, ça devient complexe !
au début j'ai essayé avec while .. read et ça
marchait super...

while read i
do
...<traitement de "$i">
done < liste.txt

mais le problème qu'il y avait c'est que je
voulais aussi utiliser un read pour confirmer ou
non d'exécuter le traitement :

ls /bidule > liste.txt

while read i
do
...<echo détails du traitement de "$i">
echo "Faire vraiment traitement de $i ?
(oui/non)" read val
if[ $val = "oui" ]; then
...<traitement de "$i">
fi
done < liste.txt

et un read dans un read ça ne fonctionne pas : le
script ne me demande pas la confirmation...

Tu fais erreur, cela fonctionne parfaitement. Sauf que le second read prend aussi son entrée dans le fichier "liste.txt" et non dans le clavier => while ... < liste.txt

Franckinux a écrit :

en fait j'aimerais mettre en place un truc
simple...si possible sinon effectivement je pourrais utiliser les autres solutions.


#!/bin/sh
# Création de la liste
ls bidule > /tmp/liste$$.txt

# Création du canal IO
exec 3</tmp/liste$$.txt

# lecture du canal IO
while read i 0<&3
do
...<echo détails du traitement de "$i">
echo "Faire vraiment traitement de $i ?
(oui/non)" read val
if [ $val = "oui" ]; then
...<traitement de "$i">
fi
done[/code]

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Re: Lister les dossiers avec un for
Auteur: Franckinux (IP enregistrée)
Date: le 24 septembre 2006 à 20:26

merci !!

à la place du ls j'ai fait :
find $CIBLE_NAME/.temp -type d > liste$$.txt


et j'obtiens : /media/mfs/files/.temp : est un répertoire

image : sue

en fait avec ls je n'arrive pas à avoir que la liste des répertoires donc j'utilise find qui tous seul en ligne de commande me renvoit pil poil ce que je veux...

image : fou ahhh ça m'rend foouuu

Re: Lister les dossiers avec un for
Avatar
Auteur: Franckinux (IP enregistrée)
Date: le 24 septembre 2006 à 20:29

image : tcontent
find $CIBLE_NAME/.temp/ -type d > liste$$.txt


faut rajouter un / !!

ça à l'air de faire ce que je veux, merci image : tcontent

Re: Lister les dossiers avec un for
Avatar
Auteur: Sve@r (IP enregistrée)
Date: le 25 septembre 2006 à 05:54

Franckinux a écrit :

en fait avec ls je n'arrive pas à avoir que la liste des répertoires

Ben ls ne fait pas tout. T'as aussi le droit de rajouter tes propres filtres
ls $CIBLE_NAME/.temp -type d > liste$$.txt
exec 3<liste$$.txt
while read i 0<&3
do
    # On élimine tout ce qui n'est pas répertoire
....test ! -d "$CIBLE_NAME/.temp/$i" && continue

....# Ici, on est certain que "$i" est un répertoire !!!
....<...>
done

Franckinux a écrit :

donc j'utilise find qui tous seul en ligne de commande me renvoit pil poil ce
que je veux...


Ca marchotte. Mais le pb est que find va jusqu'au bout de l'arborescence ce qui peut être génant si tu ne veux que la liste des répertoires qui sont juste sous "$CIBLE_NAME/.temp". Bon, je présume que "$CIBLE_NAME/.temp" n'a pas de sous sous-répertoires (style "$CIBLE_NAME/.temp/xxx/yyy/") donc ton script fonctionne dans ce cas précis mais le bug potentiel reste présent (d'où le terme "marchotte").

Eventuellement tu peux rajouter "-maxdepth 1" au find pour lui dire de ne pas descendre plus profondément qu'un niveau...

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Re: Lister les dossiers avec un for
Auteur: Franckinux (IP enregistrée)
Date: le 26 septembre 2006 à 21:00

oui merci pour le find j'ai utilisé -maxdepth 0 pour qu'il reste dans le dossier courant, et aussi avec un |sort => c'est niquel !

voilà ce que ça donne :

find $CIBLE_NAME/.temp/* -maxdepth 0 -type d|sort > liste$$.tmp

# Creation du canal IO
exec 3< liste$$.tmp

# lecture du canal IO
while read I 0<&3
do
	DEBUT=`echo $I|cut -d"/" -f6|cut -c1-3`
	DOSSIER=`echo $I|cut -d"/" -f6`
	DOSSIER_CIBLE=`echo $DOSSIER|cut -d"-" -f1`
	DOSSIER_CIBLE=`expr "$DOSSIER_CIBLE" : "\(.*\).$"`
	echo "######################################################################################"
	echo "Dossier : $I :"
	echo ""
	ls -1 "$I"
	echo ""
	NB=`ls -1 "$I"|wc -l`
	echo "$NB fichier(s)"
	echo "--------------------------------------------------------------------------------------"
	echo "Existant dans $CIBLE_NAME :"
	echo ""
	find $CIBLE_NAME/$DEBUT* -maxdepth 1 -type d|sort
	echo "--------------------------------------------------------------------------------------"
	echo -n "Deplacer vers $CIBLE_NAME ?(o/n)"; read VAL
	echo "--------------------------------------------------------------------------------------"
	if [ "$VAL" = "o" ]; then
		if [ ! -d "$CIBLE_NAME/$DOSSIER_CIBLE" ]; then
			echo "Creation de '$CIBLE_NAME/$DOSSIER_CIBLE'"
			mkdir "$CIBLE_NAME/$DOSSIER_CIBLE"
		else 
			echo "'$CIBLE_NAME/$DOSSIER_CIBLE' existe deja"
		fi
		echo "Deplacement de '$CIBLE_NAME/.temp/$DOSSIER' vers '$CIBLE_NAME/$DOSSIER_CIBLE'"
		mv $CIBLE_NAME/.temp/"$DOSSIER" "$CIBLE_NAME/$DOSSIER_CIBLE"
	fi
done

rm -f liste$$.tmp


Mais j'ai encore deux soucis que je n'arrive pas à régler :

1)je cherche a découper les chaines en fonction d'un motif qui est " - " (ce que je fais de façon salle avec DOSSIER_CIBLE partie du haut), je n'arrive pas à le faire t'aurais pas idée ?

2)Je voudrais pouvoir tout intérompre en tapant q pour quitter avec une boucle du genre :

# lecture du canal IO
while read I 0<&3
do
  while [ "$VAL" != "q" ]	
  do
       DEBUT=`echo $I|cut -d"/" -f6|cut -c1-3`
	...blablabla
       echo -n "Deplacer vers $CIBLE_NAME ?(o/n)"; read VAL
	...blablabla
  done
done


mais ça ne marche pas, pourtant cette fois si $VAL prend bien son entrée avec le clavier et non dans liste$$.txt ?


Re: Lister les dossiers avec un for
Avatar
Auteur: Sve@r (IP enregistrée)
Date: le 26 septembre 2006 à 23:09

Franckinux a écrit :

1)je cherche a découper les chaines en fonction
d'un motif qui est " - " (ce que je fais de façon sale avec DOSSIER_CIBLE partie du haut), je n'arrive pas à le faire t'aurais pas idée ?

Il n'y a rien de sale à utiliser cut, c'est fait pour ça !!!

Franckinux a écrit :

2)Je voudrais pouvoir tout interrompre en tapant q
pour quitter avec une boucle du genre :

# lecture du canal IO
while read I 0<&3
do
while [ "$VAL" != "q" ]
do
DEBUT=`echo $I|cut -d"/" -f6|cut -c1-3`
...blablabla
echo -n "Deplacer vers $CIBLE_NAME ?(o/n)";
read VAL
...blablabla
done
done

mais ça ne marche pas, pourtant cette fois ci $VAL prend bien son entrée avec le clavier et non dans liste$$.txt ?


C'est un de mes TP favoris
while read i 0<&3
do
....# Boucle de saisie infinie
....while true
....do
........echo "Déplacer vers $CIBLE_NAME ? (o/n)"; read val
........case $val in
...........[oO]|[yY]|[oO][uU][iI]|[yY][eE][sS])
................# Déplacement
................mv machin dans chose
................# Sortie boucle infinie
................break
................;;
...........[nN]|[nN][oO][nN]|[nN][oO])
................# Sortie boucle infinie
................break
...........[qQ]|[qQ][uU][iI][tT])
................# Sortie générale
................break 2
...........*)
................echo "Mauvaise réponse - Recommencez"
........esac
....done
done

Tu remarqueras la possibilité de répondre "o" comme "OuI"...

Tu devrais télécharger mon cours de shell: [fr.lang.free.fr]

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Re: Lister les dossiers avec un for
Auteur: Franckinux (IP enregistrée)
Date: le 27 septembre 2006 à 13:54

merci pour ta réponse.

2) super je connaissais pas break avec un 2 après...

1)
ben oui et non, ce que je fais ressemble à du bricolage et ne fonctionne pas dans tous les cas.
Un petit exemple s'impose !

text="chaine 1 - chaine 2"
result=`echo $text|cut -d" - " -f1`


je souhaite récupérer "chaine 1" or ici je retrouve dans $result "chaine"...


Tu devrais télécharger mon cours de shell

super merci je vais lire tout ça

Re: Lister les dossiers avec un for
Avatar
Auteur: Sve@r (IP enregistrée)
Date: le 27 septembre 2006 à 21:53

Franckinux a écrit :

merci pour ta réponse.

2) super je connaissais pas break avec un 2 après...

Tu considères la boucle dans la quelle tu te trouves de niveau 1. La boucle qui englobe celle-là est de niveau 2. La boucle qui englobe le tout est de niveau 3 etc. Ensuite, tu indiques au break (ou au continue) le niveau que tu veux quitter (ou recommencer)
break 4 => quitte la boucle de niveau 4
continue 7 => retourne à l'itération suivante de la boucle de niveau 7
Pas réllement conforme aux standards de la prog structurée mais vachement pratique...


Franckinux a écrit :

1)
ben oui et non, ce que je fais ressemble à du
bricolage et ne fonctionne pas dans tous les cas.
Un petit exemple s'impose !

text="chaine 1 - chaine 2"
result=`echo $text|cut -d" - " -f1`

je souhaite récupérer "chaine 1" or ici je retrouve dans $result "chaine"...


Je comprends pas pourquoi tu n'obtiens pas "text=chaine1" (peux pas tester, j'ai Linux qu'au boulot). Au cas ou, tu peux toujours tester ça:
result=`echo $text |cut -d"-" -f1 |sed -e "s/ $//"`


L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Re: Lister les dossiers avec un for
Avatar
Auteur: Franckinux (IP enregistrée)
Date: le 27 septembre 2006 à 23:32

merci

Je comprends pas pourquoi tu n'obtiens pas \"text=chaine1\" a écrit :

Texte à citer

moi ce que je comprend c'est que -d ne prend qu'un caractère comme délimiteur et c'est le premier donc l'espace...image : moue

result=`echo $text |cut -d"-" -f1 |sed -e "s/ $//"`

oui ça fonctionne, mais en réalité le délimiteur utilisé est toujours le premier espace, du coup si :
text="chaine-1 - chaine-2"

c'est un cas que je vais avoir aussi à gérer alors ça ne renvoit pas "chaine-1" mais "chaine"...image : fou
c'est donc pour cela que je trouve cela salle, c'est pas évident...image : sue


Re: Lister les dossiers avec un for
Avatar
Auteur: Sve@r (IP enregistrée)
Date: le 28 septembre 2006 à 00:51

Franckinux a écrit :

merci

Je comprends pas pourquoi tu n'obtiens pas
\"text=chaine1\" a écrit :Texte à citer
moi ce que je comprend c'est que -d ne prend qu'un
caractère comme délimiteur et c'est le premier
donc l'espace...

result=`echo $text |cut -d"-" -f1 |sed -e "s/
$//"`
oui ça fonctionne, mais en réalité le délimiteur
utilisé est toujours le premier espace, du coup si
:
text="chaine-1 - chaine-2"
c'est un cas que je vais avoir aussi à gérer alors
ça ne renvoit pas "chaine-1" mais "chaine"...
c'est donc pour cela que je trouve cela sale,
c'est pas évident...

Ok - Compris pour le délimiteur du cut. C'est pas un soucis...
text="chaine-1 - chaine-2"
result=`echo $text |sed -e "s/ - /-/" |cut -d"-" -f1`



L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Aller page:  12Suivante
Page courante:1 sur 2


Nom du forum : (antispam) - (en développement:saisir un texte pour le message, rempli cette zone automatiquement)
Votre nom: 
Votre email: 
Sujet: 

 
Ce forum est boosté par Phorum.