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 :

Passer des arguments dans mv à partir de 2 fichiers


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Par défaut Passer des arguments dans mv à partir de 2 fichiers
    Bonjour,

    Sous bash, j'ai 2 fichiers texte contenant des noms. Le 1er avec des noms de fichiers, le 2eme avec les nouveaux noms que ces fichiers doivent avoir.
    exemple fic1.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    abc.doc
    truc.jpg
    2.jpg
    ...
    fic2.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    abc2018.doc
    cool.jpg
    ...
    Donc, j'aimerais faire un petit mv et renommer mes fichiers en lot.
    Le problème c'est qu'un avec un seul argument je saurais faire, une boucle "while read line". Mais la commande mv à besoin de 2 arguments (l'ancien et le nouveau nom du fichier) et je suis perdu car je peux pas faire 2 boucles en même temps...

    Comment m'y prendre ?
    Pour résumer, je voudrais lire ligne par ligne chacun de mes 2 fichiers pour me servir des sorties dans une autre commande.

    Merci pour vos idées

  2. #2
    Invité
    Invité(e)
    Par défaut
    slt,

    tu peux utiliser paste
    ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    cat fic1.txt
    abc.doc
    truc.jpg
    2.jpg
     
    cat fic2.txt
    abc2018.doc
    cool.jpg
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    paste -d' ' fic1.txt fic2.txt
    abc.doc abc2018.doc
    truc.jpg cool.jpg
    2.jpg ...
    puis iterer sur ton fichier en splittant par ' '

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Par défaut
    J'ai crier victoire trop tôt...
    En faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    paste -d' ' fic1.txt fic2.txt > test.txt
    mv `cat test.txt`
    J'ai l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mv: la cible 'Stream.jpg' n'est pas un répertoire
    J'ai des noms de fichier avec des espaces, des ' et autre. Sans ça fonctionne... :'(

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 702
    Par défaut
    Bonjour,

    la solution la plus sûre (on ne sait jamais comment sont composés les noms de fichiers) est d'utiliser des descripteurs de fichiers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while read -r lineFic1 <&3; do read -r lineFic2 <&4; echo "$lineFic1 -> $lineFic2"; done 3<fic1.txt 4<fic2.txt
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Par défaut
    Testé et approuvé.
    NICKEL

    Un grand merci

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Salut,
    On peut le faire avec awk
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{a[FNR]=a[FNR]" \""$0"\""}END{for(i=1;i<=FNR;i++)system("mv "a[i])}' fic1.txt fic2.txt
    Cordialement

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 702
    Par défaut
    ça ne risque pas de poser de problèmes si un nom de fichier contient un/des espace(s) ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Pour les espaces, c'est bon.
    Si les noms de fichier comportent " ou ' , là ça le fait pas.

  9. #9
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Par défaut
    celui de N_BaH fonctionne nickel avec " ' et autre , en tout cas.

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Salut,
    Le seul problème avec awk est le " qu'il faut protéger comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{gsub(/"/,"\\\"");a[FNR]=a[FNR]" \""$0"\""}END{for(i=1;i<=FNR;i++)system("mv "a[i])}' fic1.txt fic2.txt
    avec fic1.txt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a"b "c.doc
    truc 'muche
    2.jpg
    .*
    et fic2.txt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    abc2018.doc
    cool.jpg
    3.jpg
    le point .* 
    J'ai mis en souligné pour visualiser l'espace a la fin de le point.* .
    Le code de N_Bah supprime l'espace ...
    Cordialement.

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

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Par défaut
    Bonjour,

    Faut rajouter IFS= devant les read, ainsi, on perd pas les blancs au début et/ou à la fin des lignes.

  12. #12
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 396
    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 396
    Par défaut
    En fait la méthode de N_BaH en plus propre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while { IFS="" ; read -r lineFic1 <&3 && read -r lineFic2 <&4 ; } ; do echo "$lineFic1 -> $lineFic2"; done 3<fic1.txt 4<fic2.txt
    Ici, on ne perd pas les espaces et de plus, si le fichier 2 à moins de ligne que le fichier 1, on sort aussi de la boucle sans traiter les ligne en trop du fichier 1

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 702
    Par défaut
    Attention ! le groupement de commande ({...}) ne limite pas l'étendue d'une variable, contrairement aux sous-shells ((...)) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ { IFS='n'; read v; read v2 v3; echo "$IFS";} <<<"foo
    barnbaz"
    n
    $ echo "$IFS"
    n
    $ ls
    -bash: /usr/bi: Aucun fichier ou dossier de ce type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ set -x; ls; set +x
    ++ which ls
    + /usr/bi /ls
    pour conserver les espaces, on peut ne pas nommer les variables dans read.
    il utilisera alors REPLY.
    ce qui implique, puisqu'il y a deux read (le second écrasera le précédent REPLY), de stocker le contenu du premier dans une variable "annexe"; et pourquoi pas les deux, pour faire soigné.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

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

    Et ceci ? (non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while IFS='' read -r lineFic1 <&3 && IFS='' read -r lineFic2 <&4 ; do echo "$lineFic1 -> $lineFic2"; done 3<fic1.txt 4<fic2.txt

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 702
    Par défaut
    oui.
    je n'ai pas de préférence.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  16. #16
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 396
    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 396
    Par défaut
    Même si je plussoie N_BaH, je vais être de mauvaise fois

    Ici, on est en bash (avec les settings par défaut) et on peut voir la syntaxe suivante qui fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ echo -n "$IFS" | od -t x1
    0000000 20 09 0a
    0000003
    $ : | while { IFS="" ; read -r lineFic1 <&3 && read -r lineFic2 <&4 ; } ; do echo "\"$lineFic1 -> $lineFic2\"" ; done 3<fic1.txt 4<fic2.txt                  "a"b "c.doc -> abc2018.doc"
    "truc 'muche -> cool.jpg"
    "2.jpg -> 3.jpg"
    ".* -> le point .* "
    $ echo -n "$IFS" | od -t x1
    0000000 20 09 0a
    0000003
    Mais c'est vraiment de la mauvaise fois, on exécute implicitement dans un sous-shell la boucle while et l'IFS ayant une valeur nulle ne perturbe pas les commandes simples qui ne prennent que des paramètres et si on a aussi une valeur nulle dans un des fichiers contenant la liste des fichiers, read considérera que c'est soit la fin de fichier soit il ignore totalement le nul

    Donc voici, un cas qui ne passe pas avec read :
    (bash version: 4.1.2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ while read ; do od -c <<<"$REPLY" ; done < <(echo -e "toto\x0titi")
    0000000   t   o   t   o  \n
    (bash version: 4.4.12)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ while read ; do od -c  <<<"$REPLY" ; done < <(echo -e "toto\x0titi")
    0000000   t   o   t   o   t   i   t   i  \n
    Par contre, pas de souci avec la commande awk proposée par ctac_ .

  17. #17
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Par défaut
    J'ai rien de spécial dans mon fic1, les espaces " ' et autre joyeuseté sont dans le fic2 et avec la commande de N_Bah tout est resté...
    Je vais mettre de coté la commande awk (que je ne comprends pas du tout lol) si un jour j'ai le cas de figure.

    Merci

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

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Par défaut
    Salut,

    Citation Envoyé par ctac_ Voir le message
    Salut,
    Le seul problème avec awk est le " qu'il faut protéger comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{gsub(/"/,"\\\"");a[FNR]=a[FNR]" \""$0"\""}END{for(i=1;i<=FNR;i++)system("mv "a[i])}' fic1.txt fic2.txt
    S'il faut protéger les guillemets, il faut aussi protéger tout ce qui peut être interprété par le shell entre les guillemets, le « $ » par exemple :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /tmp/test$ cat -A fic1.txt 
    a"b "c.doc$
    truc 'muche$
    2.jpg$
    .*$
    
    /tmp/test$ cat -A fic2.txt 
    abc2018.doc$
    cool.jpg$
    3.jpg$
    le $point .* $
    
    /tmp/test$ shopt -s dotglob
    
    /tmp/test$ printf '%q\n' *
    .\*
    2.jpg
    a\"b\ \"c.doc
    fic1.txt
    fic2.txt
    truc\ \'muche
    
    /tmp/test$ awk '{gsub(/"/,"\\\"");a[FNR]=a[FNR]" \""$0"\""}END{for(i=1;i<=FNR;i++)system("mv "a[i])}' fic1.txt fic2.txt
    
    /tmp/test$ printf '%q\n' *
    3.jpg
    abc2018.doc
    cool.jpg
    fic1.txt
    fic2.txt
    le\ \ .\*\  # Perte de « $point »
    Du coup, il faudrait peut-être plutôt encadrer les arguments de « mv » par des simples quotes, ainsi il n'y a que ces dernières qu'il faut protéger.

    Edit : Mouai mais non, ça donne un truc imbitable en voulant utiliser les simples quotes !

    Edit 2 : enfin, c'est faisable mais c'est laid !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{gsub(/'\''/,"'\''\\'\'\''");a[FNR]=a[FNR]" '\''"$0"'\''"}END{for(i=1;i<=FNR;i++)system("mv "a[i])}' fic1.txt fic2.txt
    Ou comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{gsub(/\047/,"\047\\\047\047");a[FNR]=a[FNR]" \047"$0"\047"}END{for(i=1;i<=FNR;i++)system("mv "a[i])}' fic1.txt fic2.txt

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

Discussions similaires

  1. Pb pour passer des arguments dans l'edi
    Par altair8080 dans le forum Code::Blocks
    Réponses: 4
    Dernier message: 17/07/2013, 10h21
  2. Réponses: 4
    Dernier message: 28/07/2009, 18h53
  3. [Cookies] passer des arguments dans un form
    Par killer_instinct dans le forum Langage
    Réponses: 2
    Dernier message: 19/04/2007, 23h36
  4. problème our passer des string dans tableau d'int
    Par Battosaiii dans le forum C++
    Réponses: 9
    Dernier message: 15/07/2004, 18h42
  5. Réponses: 5
    Dernier message: 08/03/2004, 11h28

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