Forum Linux.débutant HELP - répartir fichiers dans plusieurs dossiers

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
-2
18
jan.
2021

Bonjour,

Je fais appel à votre aide pour m'aider à trouver une commande qui permet de repartir les fichiers d'un répertoire dans plusieurs autres.

Autrement dit, j'ai un outil qui génère plusieurs dizaine de fichiers que je souhaite repartir, à l'aide d'une commande, dans plusieurs répertoires.

Une idée ?

Merci par avance

  • # Plein

    Posté par  . Évalué à 3 (+1/-0). Dernière modification le 18/01/21 à 16:34.

    Salut,

    Commencer par lire ce texte.

    Oui, je sais, ça ne t'aide pas, mais nous, ça nous aidera peut-être.

    ;)

  • # cp est une piste, mv en est une autre

    Posté par  . Évalué à 2 (+0/-0).

    la commande cp permet de copier un fichier d'un endroit à un autre

    sinon la commande mv permet de déplacer ce fichier plutot que de le copier :p

  • # Pistes

    Posté par  . Évalué à 1 (+0/-0). Dernière modification le 19/01/21 à 03:09.

    Il y a certainement plusieurs façons de faire, avant de choisir quelques questions méritent d'être répondues:

    • à quel moment sont effacés les fichiers: la durée de vie est-elle similaire ? Si elle ne l'est pas, une bonne stratégie consiste à choisir le répertoire le moins rempli, soit en nombre de fichier ou d'utilisation d'espace en fonction de l'objectif recherché. Le faire de manière efficace nécessite probablement de conserver un état pour connaître les niveaux de remplissage, la fonction de sélection devant alors aussi se charger de mettre à jour cet état. De plus, pour retrouver tes fichiers par le nom original (c'est un objectif qui peut être recherché, ou pas ?), l'état devra aussi enregistrer le mapping fichier->répertoire, vu qu'à postériori il ne sera pas possible de connaître la fonction de sélection.

    • le nombre de répertoires est-il arbitrairement limité et/ou susceptible de changer ? Une façon simple est de hacher le nom et de diviser le domaine du hash par le nombre de répertoires. Si ce nombre est voué à changer, cela devient plus compliqué. Prenons en exemple git qui stocke les objets non-empaquetés dans un répertoire qui correspond au deux première lettres de la représentation hexadécimale du hash de cet objet (soit 16*16 sous-répertoires). On peut imaginer calculer le hash à partir du nom de fichier (là ou git utilise le contenu des fichiers pour calculer son hash), ou plus simplement de prendre la ou les premières lettre(s) du fichier si la distribution des noms de fichier s'y prête. Cette méthode à l'avantage de ne pas nécessiter de maintenir un état et d'être très simple à mettre en oeuvre. Cependant elle est moins flexible.

  • # pas dur :)

    Posté par  . Évalué à 3 (+1/-0).

    for file in * 
    do
       mv "${file}" $(mktemp -d)
    done

    et voila tous les fichier et dossier du dossier courant sont déplacé dans autant de de dossiers dans ton dossier temporaire; la bonne blague c'est que si ton dossier temporaire est en ramdisk (mémoire vive), et que tu n'as pas lu / compris ce que faisait ce bout de code, ça disparaît au prochains reboot ;)

    Bon sinon on va pas faire tes exercices à ta place, mais je vais quand même aider

    • for va lister tous les fichier du dossier
    • do/done délimite la boucle
    • mv (MoVe déplace le / les fichier donnés en paramètre vers le dernier paramètre, si le dernier est un nom de dossier déplace tous les argument 1..(n-1) dans ce dossier, si ce dernier est un nom de fichier renomme le fichier/dossier 1 en 2; si tu donnes 3 ou plus arguments et que le dernier est un nom de fichier, ne marche pas
    • "${file}" utilise la variable file, les accolades permettent de délimiter le nom de variable, et les "" d'inclure les espace dans le 1er argument, sinon "un nom avec espace" sera interprété comme 4 paramètre, et évite d'autre effets de bords potentiels
    • mktemp créer un fichier/dossier temporaire, et affiche le dossier/fichier crée sur la sortie standard
    • $() exécute une sous processus et remplace le résultat de ce dernier à la place des $(), tu peux l'encadrer de ""

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: pas dur :)

      Posté par  . Évalué à 2 (+0/-0). Dernière modification le 19/01/21 à 12:13.

      Salut,

      Attention, plein de pièges quand-même : voir exemple 11-5. C'est du bash. Aucune garantie pour les autres shells, et un résultat vide peut provoquer des comportements spéciaux, disons…

      • [^] # Re: pas dur :)

        Posté par  . Évalué à 2 (+0/-0).

        plein, plein, faut pas exagérer, ça ne gère pas les fichier cachés, et si y a rien d'autre que des fichiers cachés dans le dossier, ça doit créer un dossier temporaire, et la commande mv va dire un truc du genre '*' no such file or directory

        c'est aussi pour ça que pour les cas réels j'ai tendance à préférer

        ls | while read line
        do
          [...]
        done

        ça permet de filtrer entre le ls et le while par des grep par exemple;

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

        • [^] # Re: pas dur :)

          Posté par  . Évalué à 2 (+0/-0).

          Salut,

          J'exagère certes un peu, mais ta solution (pas testé) ne me semble pas passer s'il y a un \n dans le nom d'un fichier.

          • [^] # Re: pas dur :)

            Posté par  . Évalué à 2 (+0/-0).

            effectivement dans le cas d'un nom de fichier avec \n, la solution ls | while read aura des soucis, le for i in * fonctionne :P

            En même temps sur 20 ans de bash, je ne suis jamais tombé sur un nom de fichier avec \n dedans; bon j'imagine qu'a l'avenir je me ferai un

            ls |grep -qse "." && for []

            mais généralement, je ne fais pas de for sur la totalité des fichiers d'un dossier, ça a rarement du sens :P

            Il ne faut pas décorner les boeufs avant d'avoir semé le vent

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.