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 :

Shell linux pour copie un nombre de fichier max dans un dossier et créer dynamiquement les dossier suivant


Sujet :

Shell et commandes GNU

  1. #1
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 161
    Points : 44
    Points
    44
    Par défaut Shell linux pour copie un nombre de fichier max dans un dossier et créer dynamiquement les dossier suivant
    Bonjour,

    J'ai un traitement qui va générer plusieurs milliers de fichiers et les copier dans des dossiers mais et je ne voudrais pas avoir des dossiers trop volumineux du coup je voudrais un Bach shell qui créée dynamiquement chaque dossier et qu'il copie par bloc de 5000 fichiers max et une fois le max atteint il créé un sous dossier numéroté pour mettre les 5000 suivant et ainsi de suite...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DIRA-0001, DIRA-0002, .....DIRAA-5000
    DIRB-0001, DIRB-0003, ....DIRB-5000
    quelqu'un peut m'aider svpppppppppppppp


    Merci 1000 fois

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Bonjour,
    je voudrais un Bach shell
    on ne va pas le faire pour toi.

    tu dois proposer une procédure, de la quelle tu auras déduit au moins un début de code, et nous exposer à quel moment tu coinces.

    si tu coinces dès le début, lis tes cours, et les pages en liens dans ma signature.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 802
    Points
    30 802
    Par défaut
    Bonjour ,

    Qu'as-tu déjà testé comme script ?
    Où rencontres-tu un problème ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Une boucle sur les fichiers à copier (for fic in *; do), avec deux compteurs.
    Chaque fois que le compteur atteint un nouveau cycle (1, 5001, 10001, 15001 etc ; ou plus simplement quand (cpt % 5000) == 1) tu incrémentes le second compteur et changes le dossier de destination.
    A partir de là les fichiers seront copiés dans le bon dossier.
    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]

  5. #5
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 161
    Points : 44
    Points
    44
    Par défaut
    je connais pas grand chose

    pourriez-vous m'aider svppppp

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jam92400 Voir le message
    je connais pas grand chose
    Oui, c'est le cas de chacun de nous à différents moments de sa vie. Rassure-toi, on ne te juge pas sur tes connaissances (ou dans le cas présent ton manque de connaissance). Il suffit d'apprendre. Il y a plein de tutoriels shells gratuits sur le net.

    Citation Envoyé par jam92400 Voir le message
    pourriez-vous m'aider svppppp
    Ah là en revanche je vais commener à te juger (et à mon avis je ne serai pas le seul). Déjà ces "pppppp" à suivre style "ayez pitié" je ne suis pas certain d'apprécier (ce n'est pas une question de vie ou de mort). Mais de toute façon, quel que soit mon sentiment à ce sujet, ça reste interdit par les règles du forum.
    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]

  7. #7
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 161
    Points : 44
    Points
    44
    Par défaut
    C'est ce que j'ai fais , chercher mais je bloque sur la partie compteur et la création dynamique des dossier

    pour le moment, et j'ai honte, mais j'ai que ca////:-(

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    for i in $(ls /home/monrepertoire | head -n 5000);do mv /home/monrepertoire/$i /repertoire_de_destination/ ;done

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    il y a plusieurs problèmes à l'utilisation d'une boucle for dans ce contexte :
    d'abord, on ne fait pas une boucle for sur une Substitution de commande, parce que for coupe les données en mots et pas en lignes; et on boucle encore moins sur ls.
    ensuite, la taille totale des arguments à une boucle for, bien qu'importante, est limitée
    plusieurs milliers de fichiers
    ça risque de coincer.

    je préconise, en conséquence l'emploi de find, dont la sortie standard sera connectée (utilisation d'un pipe, pour faire simple) à l'entrée standard d'une boucle while, qui lira les noms des fichiers un par un, au contraire d'une boucle for qui les aurait tout d'un coup.

    pour l'incrémentation d'une variable, il y a deux solutions
    ou
    déclarer la variable de type numérique : declare -i maVar,
    et incrémenter le variable : maVar+=1,
    ou
    utiliser un contexte arithmétique : ((maVar+=1)).

    NB : n'oublie as de réinitialiser le compteur quand il arrive à 5000
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jam92400 Voir le message
    pour le moment, et j'ai honte, mais j'ai que ca////:-(
    Il n'y a jamais de honte à avoir quand on essaye.
    Le principal souci de cet essai, c'est que tu commences par récupérer juste les 5000 fichiers que tu traites et c'est fini. Il ne faut donc pas couper avant la boucle mais dans la boucle. Donc traiter tous les fichiers et dans la boucle faire le comptage.

    Un autre souci expliqué par N_Bah c'est que "for" coupe sur l'espace. Si par exemple tu écris for x in toto titi tata tu auras 3 itérations.
    Que se passe-t-il si un fichier est un nom composé d'espace, style "mon fichier" ? Tu auras une itération sur "mon", une autre sur "fichier", les deux itérations ne feront au mieux rien (les fichiers en questions n'existent pas) et au pire tu auras une erreur style "je ne trouve pas mon" et "je ne trouve pas fichier" et dans tous les cas le fichier "mon fichier" lui ne sera pas traité.

    La solution pour traiter un nom de fichier entier, c'est à dire une ligne issue d'une commande donnant des fichiers sur une ligne (exemple ls) c'est d'utiliser read qui se cale sur le <return> terminant la ligne. Il faut donc envoyer la commande qui liste les fichiers sur une boucle qui lit l'entrée standard (donc la commande). Exemple
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ls /home/monrepertoire |while read fichier; do
    	echo "[$fichier]"
    done

    Partant de là, pas compliqué de rajouter un compteur qui change le dossier de destination chaque fois que le compteur atteint 5001 et c'est réglé.

    A noter que le principe de la commande envoyée sur le while read fonctionne avec toute commande pour peu que celle-ci retourne des lignes. J'ai montré un "ls" (qui traite un dossier), mais N_Bah a proposé un "find" (qui, lui, peut traiter toute une arborescence). A toi de choisir.
    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]

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    j'aime pas ls dans les scripts :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ ls mon* | while read fic; do echo ">$fic<"; done
    >mon<
    >fait<
    >chier<
    >monF<
    >ait    Chier<
    >monFaitChier<
    alors que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ find ./ -maxdepth 1 -type f -name 'mon*' -print0 | while IFS='' read -d '' fic; do echo ">$fic<"; done
    >./monF
    ait     Chier<
    >./mon
    fait
    chier<
    est correct.

    donc,

    ON N'UTILISE PAS ls DANS UN SCRIPT !!!!



    PS:
    le fichier qui semble manquer n'est pas un fichier, c'est un lien symbolique.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    j'aime pas ls dans les scripts
    Oui, je sais, tu me l'as dit tant de fois par le passé que ça m'est resté incrusté. Mais j'espérais qu'avec le temps tu aurais progressé sur ce point

    Citation Envoyé par N_BaH Voir le message
    alors que ...est correct)
    Euh... je n'arrive pas à reproduire le truc. Que contient le dossier au départ ? Des fichiers contenant des <return> dans leur nom ??? Je n'arrive même pas à les créer...
    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]

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    j'espérais qu'avec le temps tu aurais progressé sur ce point
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ ls -l mon*
    -rw-r--r-- 1 nbah nbah  0  8 juil.  2018 'mon'$'\n''fait'$'\n''chier'
    -rw-r--r-- 1 nbah nbah  0 15 août   2021 'monF'$'\n''ait'$'\t''Chier'
    lrwxrwxrwx 1 nbah nbah 14  5 févr.  2018  monFaitChier -> 'mon'$'\n''fait'$'\n''chier'
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    -rw-r--r-- 1 nbah nbah  0  8 juil.  2018 'mon'$'\n''fait'$'\n''chier'
    -rw-r--r-- 1 nbah nbah  0 15 août   2021 'monF'$'\n''ait'$'\t''Chier'
    lrwxrwxrwx 1 nbah nbah 14  5 févr.  2018  monFaitChier -> 'mon'$'\n''fait'$'\n''chier'
    Ouaip. Il y a les types qui pensent n'avoir pas de bol parce qu'ils traitent des dossier en automatique et tombent sur des fichiers avec des espaces dans leur nom. Et puis il y a les types qui tombent sur les dossiers N_BaH et qui se suicident

    En fait, ce n'est pas le "ls" qui pèche, c'est surtout que tu as la chance que "find" possède l'option "-print0". Parce que sans elle, ça ne marche plus...

    Mais... j'y pense soudain... ls |while read f; do printf "[%s]\n" $f; done.

    Citation Envoyé par N_BaH Voir le message
    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]

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    nope
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ ls mon* |while read f; do printf "[%s]\n" $f; done
    [mon]
    [fait]
    [chier]
    [monF]
    [ait]
    [Chier]
    [monFaitChier]
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  15. #15
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    nope
    Ouais en plus j'avais le même résultat et j'ai cru que c'était bon.

    Ah mais il doit quand-même y avoir moyen. Imagine que find n'ait pas eu le "-print0" ou que "-print0" évolue dans le futur ?
    Autre façon de formuler: s'il y avait moyen d'afficher les noms correctement (un truc dans le printf ou autre), le "ls" serait-il acceptable ?
    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]

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    non, parce que read lit jusqu'au caractère indiqué (par défaut un alinéa).
    le caractère NULL est le seul, sur les systèmes de fichiers Linux, qui ne peut pas être utilisé dans les noms de fichiers.

    -print0 se comporte un peu comme un alias pour -printf '%f\0'.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  17. #17
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 105
    Points : 4 455
    Points
    4 455
    Par défaut
    bonjour
    Citation Envoyé par jam92400 Voir le message
    j'ai que ca(
    c'est une blague ?

    1) tu écris tout sur une ligne ..., soit tu es un as en bash soit tu es un sadique qui cherche à se mettre le plus de difficultés ?
    2) Code qui n'a rien à voir avec ce que te dit de faire Sve@r ! donc, tu ne l'a pas lu ou pas fait de recherche en fonction de ces écrits ?

    As-tu testé ton code ?
    il ne faut pas commencer par exécuter tes commandes (mv x y), commence par un echo
    Débute par un code très très simple (et testable) pour arriver à ton résultat final, du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    cd "$repertoire"
    for fichier in *; do
       echo "mv $fichier vers_une_var_a_définir_plus_tard"
    done
    ps: N_BaH préconise autre chose que for, mais cela ne change en rien la logique de ton script
    Il te reste à créer des variables avant cette boucle et à les modifier dans cette bouche. Sve@r ta dit d'utiliser l'opérateur MODULO pour le changement de nom du répertoire de destination

    Citation Envoyé par jam92400 Voir le message
    je bloque sur la partie compteur
    c'est toujours la même logique :
    1) créer/initialiser une variable avant la boucle
    2) incrémenter la variable dans la boucle
    Il ne te reste qu'a tester cette variable avec l'opérateur modulo et, en fonction du résultat changer la variable "repertoire_de_destination" (voir un peu plus)
    ps: affiche cette variable "compteur" avec ton echo
    $moi= ( !== ) ? : ;

  18. #18
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 161
    Points : 44
    Points
    44
    Par défaut
    Merci merci vraiment à vous tous, je vais relire a tete reposée toutes vos recommandations et tenté de pondre un code digne de ce nom pour mon probleme

  19. #19
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in $(ls --quoting-style=shell-escape mon*); do echo $i ; done
    Cordialement.

  20. #20
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 161
    Points : 44
    Points
    44
    Par défaut
    hello

    c'est quoi ce bout de code ? j ai pas compris

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for i in $(ls --quoting-style=shell-escape mon*); do echo $i ; done

Discussions similaires

  1. Shell script pour compter le nombre de fichiers par extension
    Par andress33 dans le forum Shell et commandes GNU
    Réponses: 16
    Dernier message: 30/03/2015, 01h26
  2. Réponses: 9
    Dernier message: 11/11/2010, 13h12
  3. [AC-2002] Boucle pour importer et traiter des fichiers excel dans un dossier
    Par Tinien dans le forum VBA Access
    Réponses: 9
    Dernier message: 02/06/2010, 11h59
  4. Réponses: 2
    Dernier message: 15/06/2009, 18h41
  5. Réponses: 7
    Dernier message: 10/10/2007, 19h23

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