IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Un mystère de comptage pour éliminer "ls"


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 127
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 127
    Par défaut Un mystère de comptage pour éliminer "ls"
    Re-bonjour,

    Je veux compter sans ls les objets dans un dossier, et ça semble très facile, exemple avec mon dossier /tmp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ count=0; for obj in /tmp; do count=$((count+1)); done; echo $count
    1
    $ count=0; for obj in /tmp/; do count=$((count+1)); done; echo $count
    1
    $ count=0; for obj in /tmp/*; do count=$((count+1)); done; echo $count
    11
    Voilà donc la bonne syntaxe, sur cette dernière ligne.
    OK.

    Maintenant, je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ target=/media/vide
    $ mkdir $target
    $ count=0; for obj in $target/*; do count=$((count+1)); done; echo $count
    1
    C'est quoi ce "1" ? D'autant plus que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ ls /media/vide
    (ligne vide)
    $ ls -l /media/vide
    total 0
    Ah, cette imbécile de boucle se compte elle-même !, ça se voit bien à l'ajout de echo $obj :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ count=0; for obj in $target/*; do echo "$obj"; count=$((count+1)); done; echo $count
    /media/vide/*
    1
    La bonne syntaxe, avec un test de validité de la variable $obj :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ count=0; for obj in $target/*; do [ -f "$obj" ] && count=$((count+1)); done; echo $count
    0
    $ touch /media/vide/bidon1; touch /media/vide/bidon2; touch /media/vide/bidon3
    $ count=0; for obj in $target/*; do [ -f "$obj" ] && count=$((count+1)); done; echo $count
    3
    $ rm $target/*
    (yCR yCR yCR)
    $ count=0; for obj in $target/*; do [ -f "$obj" ] && count=$((count+1)); done; echo $count
    0
    Ça a l'air correct, alors cadeau.

  2. #2
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 288
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find ~ -printf "." | wc -c
    34168
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ rm -f ~/testalanoix.txt;find ~ -printf "." | wc -c; >~/testalanoix.txt; find ~ -printf "." | wc -c
    34159
    34160

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Petit ajout :
    Peut-être cela mérite un nouveau topic histoire de ne pas saturer celui-là (si on commence à répondre aux deux sujets à la fois...)
    [edit]Ah, un modo (je suppute que c'est N_BaH) a fait le transfert/scindage de topic

    Citation Envoyé par Jipété Voir le message
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ count=0; for obj in $target/*; do [ -f "$obj" ] && count=$((count+1)); done; echo $count
    0
    Ça a l'air correct, alors cadeau.
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    count=0; while read obj; do count=$((count+1)); done < <(find "$target"/* 2>/dev/null); echo "$count"
    0
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Septembre 2021
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2021
    Messages : 5
    Par défaut
    Pourquoi vous l'avez appeler un truc ?

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Germain Kausa Voir le message
    Pourquoi vous l'avez appeler un truc ?
    Bonjour, merci, c'est quand tu veux. Tu rentres dans un topic tu dis "bonjour". On te demande pas de le dire à chaque post mais pour le premier du topic.
    Tu veux bien citer la partie dont tu parles qu'on puisse comprendre ta question??? C'est facile, tu fais "répondre avec citation" puis tu supprimes ce qui est en trop...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 349
    Par défaut
    Non, c'est parce que j'avais posté une réponse par mégarde qui ne fonctionne pas et que j'ai supprimé

  7. #7
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Ah, cette imbécile de boucle se compte elle-même !, ça se voit bien à l'ajout de echo $obj
    en bash, il y a l'option nullglob de shopt pour éviter ça.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 349
    Par défaut
    Surtout que test -f check si c'est un fichier "régulier", donc ne compte pas les répertoire et autre type de fichiers possible (socket,bloc,...)

  9. #9
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 127
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 127
    Par défaut
    Bonjour,

    Alors j'ai fait help set et je suis tombé sur ça :
    Citation Envoyé par help_set
    -- Affecte tous les arguments restants aux paramètres de position.
    S'il n'y a plus d'argument, les paramètres de position sont indéfinis.
    qui ne m'avance absolument pas, ne voyant pas du tout de quoi on parle : quels arguments restants ? Quels paramètres de position ?

    Mais comme tout sert à tout, ça m'a fait lire l'aide bash de set, et à qui faut-il écrire pour faire corriger les fautes d'orthographe ?

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Jipété Voir le message
    qui ne m'avance absolument pas, ne voyant pas du tout de quoi on parle : quels arguments restants ? Quels paramètres de position ?
    Quand tu crées un programme pour qu'il effectue une tâche, tu peux le prévoir pour que les élements nécessaire à sa tâche lui soient passés lors de l'appel. Exemple le programme "cp" recevra deux éléments de travail: la source et la destination.
    Ces éléments sont passés après le nom du programme et avant le <return>. On les nommes "arguments du programme" => cp toto titi.

    Du côté programme, ces élements sont stockés dans des variables numérotées "$1", "$2", "$3", etc. qu'on nomme "paramètres de position" de par l'évidente corrélation entre les numéros des variables (1, 2, 3, etc) et la liste des arguments reçu (premier, second, troisième, etc). Ainsi dans l'exemple, "$1" contient "toto" et "$2" contient "titi". Plus "$#" qui contient le nombre d'arguments (ici 2), plus "$*" qui contient tous les arguments sous forme de chaine unique (donc "toto titi") et "$@" qui contient tous les arguments sous forme de chaines individuelles (donc "toto" "titi"). Plus "$0" qui contient le nom du programme tel qu'il a été invoqué en ligne de commande (ici "cp")
    Ce stockage est automatique. C'est bash qui le fait lors de l'appel.

    La commande set permet de réaffecter manuellement toutes ces variables. Si par exemple tu tapes l'instruction set xxx yyy zzz alors avant l'instruction tu as "$1" qui contient "toto", après l'instruction tu as "$1" qui contient "xxx" (et pareil pour tous les autres). Sauf "$0" qui reste inchangé.

    Ca peut être utile par exemple pour explorer ton chemin pwd. Tu tapes IFS=/ set "$(pwd)" et tu as tout ton pwd explosé dans $1, $2, $3, etc...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ (IFS='/' set -- "$(pwd)"; printf '%s\n' "$@")
    /home/nbah
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    /home/nbah
    Oui, tu as raison. J'ai écrit cet exemple en partant d'un de mes codes mais j'ai voulu l'adapter à une syntaxe que j'ai apprise récemment dans laquelle on écrit var=valeur instruction et dans laquelle la variable n'existe que pour l'instruction.
    Donc je l'ai tapée sans la tester, en partant du principe que ça allait fonctionner puisqu'elle me semblait similaire à celle de mon code. Or après examen/test effectivement elle ne fonctionne pas.

    Voici un exemple créé à partir de mon code d'origine qui, lui, fonctionne
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
     
    oldifs="$IFS"
    IFS="/"
    set $(pwd)
    IFS="$oldifs"
     
    echo "[$1]"
    echo "[$2]"
    echo "[$3]"

    Et si on shunte maintenant la phase "sauvegarde puis restauration de l'IFS" en raccourcissant tout ça via un IFS=/ set $(pwd) ça ne fonctionne plus. Je ne peux que dire "désolé je ne sais pas pourquoi" mais c'est un peu de ta faute, c'est toi qui m'a appris var=valeur instruction

    Bon enfin c'est pas vraiment grave, l'important c'est que Jipété comprenne l'idée que mon exemple a voulu exprimer.

    PS: a noter aussi que si on remplace set $(pwd) par set "$(pwd)" là non plus ça ne fonctionne pas. Ok là c'est ma faute, j'ai voulu appliquer mes principes de quoter systématiquement toute string mais il semble que ça s'accorde mal avec l'IFS (et les quotes n'y sont d'ailleurs pas dans mon code d'origine )

    PS2: le code en question est disponible sur ce forum... https://frederic-lang.developpez.com...divers#LXIII-I

    PS3: en fait je pense que je n'ai pas compris var=valeur instruction car quand je tape toto=123 echo "[$toto]" j'obtiens "[]"
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  13. #13
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 349
    Par défaut
    IFS = Input Field Separator

    Donc, pour des commandes internes au shell qui ne prennent pas de données en entrée (le cas de set), ça ne fonctionne pas, faut que la variable soit changée pour le shell en lui même car c'est lui qui prend l'entrée pour fournir les paramètres à la commande.

    Cela fonctionne pour "read" car lui attend bien quelque chose en entrée.

    Question: pourquoi "$(pwd)" et pas la variable "$PWD" ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. cherche commande unix pour éliminer les données communes
    Par astrolane dans le forum Applications et environnements graphiques
    Réponses: 3
    Dernier message: 07/12/2009, 17h23
  2. [MySQL] Requête pour éliminer les enregistrements NULL
    Par gtraxx dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 12/03/2009, 09h09
  3. audacity pour éliminer le bruit
    Par zhpipo16 dans le forum Audio
    Réponses: 5
    Dernier message: 16/04/2008, 20h56
  4. Pb pour éliminer les caractères alpha
    Par chouffe dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 08/12/2005, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo