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 :

Copier un fichier dans les derniers sous dossier


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut Copier un fichier dans les derniers sous dossier
    Bonjour,

    d'habitude j'utilise la commande suivante pour copier mon fichier dans les dossiers:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ls -d */ | xargs -n 1 cp -v fichier.txt
    avec une arborescence du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ls dossier_1
    text1 text2

    mais, cette fois-ci je souhaite copier un fichier dans les derniers sous dossier;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    dossier_1 dossier_2 
    ls dossier_1
    dossier_11 dossier_12
    ls dossier_11
    text1 text2 text3
    ls dossier_2 
    dossier_21 dossier_22
    Comment copier un même fichier mais uniquement dans le dernier sous dossier?

    car en ajoutant la fonction recursive de cp, cela copie ce meme fichier mais dans tout les sous dossier or je veux uniquement le dernier sous dossier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ls -d */ | xargs -n 1 cp -v -r  fichier.txt


    Merci,

    Hamtaroux

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    ON N'UTILISE PAS ls DANS UN SCRIPT !!!
    ou pour en parser la sortie !

    il faut que tu définisses "dernier sous-dossier", car cela n'a pas de sens au niveau du système de fichier.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut
    ce n'est pas un script en fait, je comptais faire ça directement sur le terminal;

    du coup vaut mieux écrire un script c'est ca?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    non, tu peux faire ça (enfin, non, pas ça, pas comme ça ) sur la ligne de commande, il faut seulement ne pas utiliser ls pour autre chose qu'afficher les données, pas les parcourir*.

    il faut que tu définisses "dernier sous-dossier"
    une fois cela défini, on verra par quel bout le prendre soit en 100% bash, soit avec find...

    * c'est une question de bonnes pratiques (best practices), car les noms de fichiers peuvent contenir des caractères contenus dans l'IFS, ce qui peut nuire à leur lecture/restitution.
    imagine un fichier dont le nom serait , son utilisation par une commande lisant la sortie de ls ne sera pas correcte : elle lira trois entités mon, fic, hier, au lieu de 'mon fic'$'\nhier'
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut


    en fait je souhaite copier le fichier "FICHIER.txt" dans les chemins commençant par:

    I1 I2 I3 I4 I5 I6

    l'architecture est la suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    hamtaroux:~/Bureau$ ls
    I1/ I2/ I3/ I4/ FICHIER.txt DOSSIER_QUELCONQUE/
    hamtaroux:~/Bureau$ ls I1/
    X_1_3/
    hamtaroux:~/Bureau$ ls I1/X_1_3/
    p_10/  p_15/  p_19/  p_24/  p_28/  p_8/
    hamtaroux:~/Bureau$ ls I2/X_2_5/
    p_10/  p_15/  p_20/  p_25/  p_30/  p_5/

    Ce que j'essaye de faire c'est de copier FICHIER.txt dans I*/*/*: et d'avoir:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    hamtaroux:~/Bureau$ ls I1/X_1_3/p_10/
    FICHIER.txt
    hamtaroux:~/Bureau$ ls I1/X_1_3/p_15/
    FICHIER.txt
    et de ne pas avoir ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    hamtaroux:~/Bureau$ ls I1/X_1_3/
    p_10/  p_15/  p_19/  p_24/  p_28/  p_8/ FICHIER.txt
    hamtaroux:~/Bureau$ ls I1/
    X_1_3 FICHIER.txt


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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    ce n'est pas si simple : il faut réfléchir à comment trouver le répertoire le plus profond sous un répertoire donné.
    le chemin du répertoire le plus profond contiendra le nombre le plus élevé de slashes.

    d'abord, tu dois savoir comment afficher la liste des répertoires avec bash, il faut positionner l'option globstar avec shopt, puis faire une boucle for pour pouvoir traiter les répertoires l'un après l'autre,
    ensuite, il faut retirer tous les caractères autres que le slashes (avec tr, ou sed) pour pouvoir les compter
    ...
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -type d | awk -F'/' '{a[NF]=a[NF]"\n"$0;if (NF>max) max=NF;} END{print a[max];}'|xargs -n 1 cp -v file.txt
    Le premier étage liste les dossiers.
    Le deuxième étage sélectionne les plus longs.
    Le troisième étage est le tien, recopié.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    pourvu qu'il n'y ait pas d'espaces, ou de retours à la ligne dans les noms des répertoires !

    cf. best practices
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Oui. Je n'aurais pas dû recopier le dernier étage.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -type d | awk -F'/' '{a[NF]=a[NF]"\n"$0;if (NF>max) max=NF;} END{print a[max];}'|xargs -ITT cp -v file.txt TT
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    tu as pu faire quelques tests; je ne suis pas sûr que cela arrange "les choses".

    il est recommandé, pour parer à toute éventualité, de faire un -print0; le caractère NULL étant le seul à ne pas pouvoir être employé dans un nom de fichier/dossier.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut
    wow j'ai essayé cette commande çà marche très bien ! Merci beaucoup

  12. #12
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut
    petite question les fonctions ITT et TT qu'est ce qu'elles signifient ?

    et le -print0 devrait se placer ou exactement?

  13. #13
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut
    dans le manuel ça me donne ceci:

    -I replace-str
    Replace occurrences of replace-str in the initial-arguments with
    names read from standard input. Also, unquoted blanks do not
    terminate input items; instead the separator is the newline
    character. Implies -x and -L 1.


    -t, --verbose
    Print the command line on the standard error output before exe‐
    cuting it.

  14. #14
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut
    dans mon cas ça marche, car les dossiers qui ne m’intéresse pas sont plus court < 4 en longueurs max;

  15. #15
    Membre à l'essai Avatar de Hamtaroux
    Femme Profil pro
    Doctorante
    Inscrit en
    Juillet 2019
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Doctorante

    Informations forums :
    Inscription : Juillet 2019
    Messages : 23
    Points : 17
    Points
    17
    Par défaut
    Du coup pour mon cas j'ai ajouté une étage supplémentaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    find . -type d | awk ' { if($1 ~ /I2/ ) print  $0 }' | awk -F'/' '{a[NF]=a[NF]"\n"$0;if (NF>max) max=NF;} END{print a[max];}'|xargs -ITT cp -v file.txt TT
    "

    Maintenant je me demandais si c'était possible de faire une boucle pour I2 à I5 par exemple;


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     for i in `seq 2 1 5`; d
    o find . -type d | awk ' { if($1 ~ /I${i}/ ) print  $0 }' | awk -F'/' '{a[NF]=a[NF]"\n"$0;if (NF>max) max=NF;} END{print a[max];}'; done

    Mais ca fonctionne pas; peut etre faire un echo avant le awk pour mettre I2 , ...I5 en variable; comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    echo "I2 I3" | awk ' { if ($1 ~ /$1/ )
    mais si je fais ça il y a un problème avec les colonnes

  16. #16
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    J'ai pas compris l'histoire de "inférieur à 4".

    L'étage que tu as ajouté est inutile. Préciser le script suffit. Voir plus bas.

    Pour ta boucle, note bien qu'il y a les variables de la commande bash, et les variables du script awk. Et ce ne sont pas les mêmes.
    Les variables du script bash ne sont pas interprétées entre simple quote ' '. Mais elles le sont entre double quote " ".
    Le script awk étant entre simple quotes (pour le protéger efficacement), ta solution ne pouvait marcher.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -type d | awk -F'/' '($1 ~ /I[235]\>/){a[NF]=a[NF]"\n"$0;if (NF>max) max=NF;} END{print a[max];}'|xargs -ITT cp -v file.txt TT
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    shopt -s nullglob globstar
    declare -i max=0
    for d in "${srcDir:-.}"/**/*/; do depth=$(tr -c -d '/' <<< "$d"); (( ${#depth} > max )) && { deepest="$d"; max=${#depth};}; done
    echo "$deepest"
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  18. #18
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Super intéressant.

    Les dossiers "deepest" sont plusieurs et doivent apparaître en sortie.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (( ${#depth} > max )) && { deepest=(); max=${#depth};}; (( ${#depth} >= max )) && deepest+=( "$d" )
    ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  20. #20
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    le "dernier répertoire", c'est donc un répertoire qui n'en contient pas d'autre, ou dit autrement qui ne contient que . et ..

    je propose donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -type d -links 2 -exec cp fichier {} \;
    et le résultat :
    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
    $ tree --charset ascii
    .
    |-- fichier
    `-- rootdir
        |-- dir1
        |   `-- dir1
        |       |-- dir1
        |       |   `-- fichier
        |       `-- dir2
        |           `-- dir1
        |               `-- fichier
        |-- dir2
        |   `-- fichier
        `-- dir3
            `-- dir1
                `-- dir1
                    `-- fichier

Discussions similaires

  1. recuperer seulement les derniers sous dossiers d'un repertoire
    Par dalila15 dans le forum Débuter avec Java
    Réponses: 12
    Dernier message: 24/02/2017, 13h53
  2. Copier un fichier dans chaque sous-dossier grace a command !
    Par k3vin dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 26/12/2009, 17h15
  3. Copier un fichier dans tous les dossier qui contiennent un .ini
    Par proteine1024 dans le forum VBScript
    Réponses: 12
    Dernier message: 17/09/2009, 08h19
  4. [XL-2007] copier des textbox dans les dernieres lignes vides
    Par dodo28 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 18/08/2009, 18h37

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