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 :

Parcourir une arborescence puis traitement sur fichier


Sujet :

Shell et commandes GNU

  1. #1
    Candidat au Club
    Inscrit en
    Décembre 2013
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Parcourir une arborescence puis traitement sur fichier
    Bonjour,
    je voudrais parcourrir une arborescence de répertoire et sous répertoire, et pour chacun des fichiers de l'arborescence je voudrais créer un lien symbolique sur ce fichier, dans un répertoire "lien", en le nommant de la manière suivante:
    "Fichier_".(NombreAleatoire de 0 à1000000).(extension du fichier d'origine).

    -sans dépacer/supprimer les fichiers d'origine.
    -en mettant tous les liens créés dans un seul et même répertoire.
    -(et si possible mais pas indispensable) en ayant le même nombre de digit pour le nombre aléatoire.

    Exemple:
    C:/arbo/rep1/rep11/toto.jpeg
    C:/arbo/rep2/rep21/rep211/titi.Gif
    C:/arbo/rep3/tata.txt
    
    ==> C:/lien/Fichier_138464.jpeg
    ==> C:/lien/Fichier_751482.Gif
    ==> C:/lien/Fichier_276415.txt

    je suis débutant et en parcourant le forum j'ai trouvé des bouts de scripts et comandes: "find", "ln -s","basename (pour récupérer le nom du fichier)"
    mais
    -Comment récupérer l'extension du fichier?
    -Comment générer et concaténer un nombre aléatoire?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/sh
    for i in `find <chemin> -type f`
    do
     target_dir=`lien`
     j=(NombreAleatoire de 0 à1000000) ????
     k=(extension du fichier d'origine) ????
     ln - s $i ./$target_dir/`Fichier_'. $j.$k
    done
    exit0
    Merci d'avance de votre aide.
    Cordialement,

  2. #2
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Salut,
    Si tu n'es pas contre bash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/bin/bash
    shopt -s globstar
    for fic in **/*.*
    do
       [[ ! -f $fic ]] && continue
       ext=${fic##*.}
       i=0
       while [[ -L lien/Fichier_.$nb.$ext || $i = 0 ]]
       do
          nb=$(printf '%07d' $(((RANDOM%1000)*(RANDOM%1000))))
          ((i++))
       done
       ln -s "$fic" "lien/Fichier_.$nb.$ext"
    done

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    Bonjour Postmortem, et bienvenue.

    il est préférable de mettre systématiquement les variables entre quillemets (surtout dans les tests).

    une option pour éviter la création d'un sous-shell :printf -v nb '%07d' $(((RANDOM%1000)*(RANDOM%1000))).

    les doubles-crochets ne sont pas nécessaires ici : des crochets simples pour des tests simples.

    trois fois rien, quoi

  4. #4
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Bonjour Postmortem, et bienvenue.
    Merci ! Et merci pour tous tes messages car j'ai appris plein de trucs en les lisant (et ceux d'autres membres réguliers).

    Citation Envoyé par N_BaH Voir le message
    il est préférable de mettre systématiquement les variables entre quillemets (surtout dans les tests).

    une option pour éviter la création d'un sous-shell :printf -v nb '%07d' $(((RANDOM%1000)*(RANDOM%1000))).

    les doubles-crochets ne sont pas nécessaires ici : des crochets simples pour des tests simples.

    trois fois rien, quoi
    J'avais jamais fait gaffe que printf acceptait l'option -v, je le note, merci !

    Pour les tests, je les fais systématiquement entre [[ ]] (sauf dans certains cas), question d'habitude... Et du coup, les guillemets ne sont pas nécessaires, même si la valeur de la variable contient une espace (pas de découpage en mots après les expansions quand on est entre [[ ]] il me semble). Après, mieux vaut en mettre trop que pas assez !

  5. #5
    Candidat au Club
    Inscrit en
    Décembre 2013
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Parcourir une arborescence puis traitement sur fichier
    Bonjour et merci bcp pour votre réponse et votre aide!
    et désolé si mes questions sont basiques, je suis gros débutant!

    @postmortem: merci pour le bout de script qui est très clair.

    je voudrais le faire tourner sur mon NAS (dlink325) avec un linux 2.6.22.18 installé.
    J'ai l'impression que les comandes shopt, globstar?, RANDOM ne sont pas reconnues.
    Est-ce possible?
    Ai-je une version de bash trop ancienne?
    dois-je/puis-je la mettre à jour? comment?
    le cas échéanr puis-je faire l'équivalent en sh?

    merci, a+

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    si shopt n'est pas reconnu, alors soit bash n'est pas installé, soit sh n'est pas un lien vers bash.


    pour générer des nombres aléatoires :
    existe-t-il un fichier /dev/urandom ?
    awk est-il disponible ?

  7. #7
    Candidat au Club
    Inscrit en
    Décembre 2013
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Bonjour,
    Contrairement à ce que j'ai dit:
    Quand je regarde les shells installés (cat /etc/sells): il m'indique que les suivants sont installés:
    -/ffp/bin/Bash (3.2.33)
    -/ffp/bin/sh
    -/bin/Bash (mais je ne les trouve pas dans le répertoire /bin)
    -/bin/Bash2 (mais je ne les trouve pas dans le répertoire /bin)
    -/bin/sh (mais je ne les trouve pas dans le répertoire /bin)
    En bash (je tape bash dans l'invite),
    Quand je tape la commande "shopt": il la connait bien, et me liste un certain nombre d'info.
    Quand je tape la commande "random": il répond "command not found", à moins qu'elle ne peut-être appelée que dans les scripts ! ?

    -le fichier /dev/urandom existe de même que /dev/random.
    -awk (3.1.6) est dispo

    Par défaut mon shell est sh: comment mettre bash par défaut de manière permanente ?
    Je pense que c'est globstar qui n'est pas connu. Dois-je l'ajouter pour parcourir l'arbo et récupérer l'extension des fichiers comme indiqué par postmortem ? Comment l'ajouter (si besoin) ? Ou y a-t-il un autre moyen de le faire sans globstar ?
    Merci pour ton aide, c'est super sympa !.

  8. #8
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Voici une façon portable de le faire, c'est à dire ne s'appuyant pas sur des spécificités de bash ou autre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    src=arbo   # répertoire où chercher les fichiers
    dest=liens # répertoire où créer les liens
     
    PATH=$(getconf PATH):$PATH
    [ ! -d "$dest" ] && { mkdir "$dest" || exit 1 ; }
    find "$src" -type f -exec sh -c '
    ext=${0##*.}
    [ "$ext" = "$0" ] && ext="none"
    while true; do
            target='"$dest"'/$(printf "%04d%04d\n" $((RANDOM%1000)) $((RANDOM%1000)) ).$ext
            [ -L "$target" ] && continue
            ln -s "$0" "$target" && break
    done' {} \;

  9. #9
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 302
    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 302
    Points : 12 795
    Points
    12 795
    Par défaut
    Bonjour,

    Juste sur le point du random, en bash, il s'agit d'une variable $RANDOM
    qui permet d'avoir un nombre alétoire a chaque consultation de celle-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ echo $RANDOM
    4404
    $ echo $RANDOM
    8686
    $ echo $RANDOM
    13894
    $ echo $RANDOM
    24656
    $ echo $RANDOM
    16770
    $ echo $RANDOM
    26162

  10. #10
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Salut,
    Si je peux me permettre une petite question, que fait cette ligne ?
    Citation Envoyé par jlliagre Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PATH=$(getconf PATH):$PATH
    J'ai consulté le man mais je pige pas trop ce getconf... Et il n'est pas dispo sur cygwin, du coup je ne peux essayer.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    Voici une façon portable de le faire

    printf n'est pas POSIX.
    RANDOM non plus.

  12. #12
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Citation Envoyé par Postmortem Voir le message
    Salut,
    Si je peux me permettre une petite question, que fait cette ligne ?
    Elle permet d'avoir un PATH qui met en premier les commandes conformes au standard POSIX.
    J'ai consulté le man mais je pige pas trop ce getconf... Et il n'est pas dispo sur cygwin, du coup je ne peux essayer.
    J'ai envisagé que la commande ne soit pas disponible en ajoutant le PATH original à la fin, ça ne devrais pas impacter tes tests donc.

  13. #13
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Citation Envoyé par N_BaH Voir le message

    printf n'est pas POSIX.
    Il n'y a pas plus POSIX que printf. Le standard recommande d'ailleurs d'utiliser printf plutôt que la commande echo qui n'a pas un comportement prévisible.
    RANDOM non plus.
    C'est vrai, POSIX n'a pas retenu RANDOM pour ses specs mais je demande à voir un shell (bourne) qui ne l'implémente pas.

  14. #14
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    Elle permet d'avoir un PATH qui met en premier les commandes conformes au standard POSIX.

    J'ai envisagé que la commande ne soit pas disponible en ajoutant le PATH original à la fin, ça ne devrais pas impacter tes tests donc.
    Merci pour l'info.
    En fait, je voulais surtout tester ce que renvoyait getconf. Je regarderai plus tard chez moi.

  15. #15
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Citation Envoyé par Postmortem Voir le message
    je voulais surtout tester ce que renvoyait getconf. Je regarderai plus tard chez moi.
    En fait, getconf est disponible avec cygwin depuis la version 1.7.10 (février 2012) http://cygwin.com/ml/cygwin-announce.../msg00008.html

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    Il n'y a pas plus POSIX que printf.


    je demande à voir un shell (bourne) qui ne l'implémente pas
    dash n'a pas RANDOM;
    sh, dans freeBSD, non plus

  17. #17
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    J'avais dit "un" shell, pas "deux"

    Bon RANDOM étant moins universel que je le pensais, voici une version plus portable ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    src=arbo
    dest=liens
     
    [ "$(getconf PATH)" ] && PATH=$(getconf PATH)
    [ ! -d "$dest" ] && { mkdir "$dest" || exit 1 ; }
     
    find "$src" -type f -exec sh -c '
    random() {
      awk -v rnd=$2 -v max=$1 "BEGIN {srand(rnd); rand(); printf(\"%d\",int(rand()*max)) }"
    }
    for i do
      ext=${i##*.}
      [ "$ext" = "$i" ] && ext="none"
      while true; do
        rnd=$(random 1000000 $rnd)
        target='"$dest"'/$(printf "%06d\n" $rnd).$ext
        [ -L "$target" ] && continue
        (set -x;ln -s "$i" "$target") && break
      done
    done ' sh {} +

  18. #18
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    J'avais dit "un" shell, pas "deux"

    Bon RANDOM étant moins universel que je le pensais, voici une version plus portable ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    src=arbo
    dest=liens
     
    [ "$(getconf PATH)" ] && PATH=$(getconf PATH)
    [ ! -d "$dest" ] && { mkdir "$dest" || exit 1 ; }
     
    find "$src" -type f -exec sh -c '
    random() {
      awk -v rnd=$2 -v max=$1 "BEGIN {srand(rnd); rand(); printf(\"%d\",int(rand()*max)) }"
    }
    for i do
      ext=${i##*.}
      [ "$ext" = "$i" ] && ext="none"
      while true; do
        rnd=$(random 1000000 $rnd)
        target='"$dest"'/$(printf "%06d\n" $rnd).$ext
        [ -L "$target" ] && continue
        (set -x;ln -s "$i" "$target") && break
      done
    done ' {} +
    Cette solution ne traite pas le tout premier fichier trouvé par find
    Il faut rajouter un mot juste avant {} +

  19. #19
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Citation Envoyé par Postmortem Voir le message
    Cette solution ne traite pas le tout premier fichier trouvé par find
    Il faut rajouter un mot juste avant {} +
    Bien vu, merci !
    script corrigé.

  20. #20
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    Je crois qu'il est temps que le week-end arrive !!
    Ca serait plutôt :

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/02/2023, 18h27
  2. Cherche une commande shell/bash pour traitement sur fichier
    Par breizho35 dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 26/02/2015, 11h18
  3. Parcourir une arborescence de fichiers sous Unix
    Par dim_italia dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 04/12/2007, 15h35
  4. Réponses: 3
    Dernier message: 16/03/2007, 18h04
  5. Parcourir une arborescence et comparer ses fichiers
    Par Doom2Darkness dans le forum Linux
    Réponses: 6
    Dernier message: 04/01/2007, 13h55

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