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 :

Intercaler une colonne d'un fichier dans un autre


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 32
    Points : 23
    Points
    23
    Par défaut Intercaler une colonne d'un fichier dans un autre
    Bonjour,

    J'ai un fichier_1 composé d'une seule colonne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    COL_1_FIC_1
    AZERTY
    QSDFG
    WXCVB
    J'ai un second fichier_2 composé de 3 colonnes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    COL_1_FIC_2   COL_2_FIC_2      COL_3_FIC_2
    ABC                123                10292
    ABC                456                2030Z
    ABC                789                20304
    Je souhaite intercaler la colonne de mon fichier_1 entre deux colonnes du fichier_2. Ce qui peut ressembler à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    COL_1_FIC_2   COL_2_FIC_2         COL_1_FIC_1           COL_3_FIC_2     
    ABC                123                 AZERTY            10292              
    ABC                456                 QSDFG              2030Z              
    ABC                789                 WXCVB             20304
    La commande unix paste permet fusionner les colonnes en mettant la colonne du fichier_1 soit au début ou à la fin du fichier_2 mais pas ailleurs.
    Une idée ?

    Merci infiniment

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 593
    Points : 19 471
    Points
    19 471
    Par défaut
    Bonjour,

    ici ?

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 728
    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 728
    Points : 31 050
    Points
    31 050
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Taxan Voir le message
    La commande unix paste permet fusionner les colonnes en mettant la colonne du fichier_1 soit au début ou à la fin du fichier_2 mais pas ailleurs.
    Une idée ?
    Bonjour
    Oui, une idée (pas bien compliqué d'ailleurs) : utiliser cut pour découper le fichier 2 en deux fichiers 2A (2 colonnes) et 2B (une colonne) puis utiliser paste sur le fichier 2A, le fichier 1 et le 2B.

    Ca c'est la méthode la plus simple à concevoir et donc la plus "bas de gamme". Tu peux aussi envoyer le paste de tes deux fichiers initiaux (donc t'auras tes 4 infos dans un ordre qui ne te convient pas) sur une commande awk qui se chargera, elle, de remettre les 4 infos dans le bon ordre. Un peu dans ce style paste fichier_1 fichier_2 |awk '{printf("%s %s %s %s\n", $2, $3, $1, $4)}'...

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 32
    Points : 23
    Points
    23
    Par défaut
    Je vous remercie pour vos retours.
    Le besoin est rendu un peu plus complexe. Je vais essayer d'être clair :

    J'ai toujours mon fichier_1 dont le nombre de champs est variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CHAMP1_1|CHAMP1_2|CHAMP1_3|..........|CHAMP_1_N
    Mon second fichier_2 dont le nombre de champs est variable aussi mais il est forcément égal au nombre de champs du fichier_1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    VAL1_1|VAL1_2|VAL1_3|..........|VAL1_N
    VAL2_1|VAL2_2|VAL2_3|..........|VAL2_N
    VAL3_1|VAL3_2|VAL3_3|..........|VAL3_N
    Mon objectif est d'obtenir ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CHAMP1_1|VAL1_1|CHAMP1_2|VAL1_2|CHAMP1_3|VAL1_3......|CHAMP_1_N|VAL1_N
    CHAMP1_1|VAL2_1|CHAMP1_2|VAL2_2|CHAMP1_3|VAL2_3......|CHAMP_1_N|VAL2_N
    CHAMP1_1|VAL3_1|CHAMP1_2|VAL3_2|CHAMP1_3|VAL3_3......|CHAMP_1_N|VAL3_N
    En réalité, dans le fichier_1, j'ai ma liste de champs et dans le second fichier_2, les valeurs associées à cette liste de champs.
    Donc, ma liste de CHAMP_X_Y se répète autant de fois qu'il y a de lignes dans le second fichier.

    Désolé chers experts de vous déranger à nouveau. J'espère que ma demande est plus claire.
    Merci pour votre aide.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 728
    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 728
    Points : 31 050
    Points
    31 050
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Taxan Voir le message
    Je vous remercie pour vos retours.
    Le besoin est rendu un peu plus complexe. Je vais essayer d'être clair :
    C'aurait été bien de l'être dès le départ. Nous, on ne peut se baser que sur ce que tu dis quoi...

    Citation Envoyé par Taxan Voir le message
    J'ai toujours mon fichier_1 dont le nombre de champs est variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CHAMP1_1|CHAMP1_2|CHAMP1_3|..........|CHAMP_1_N
    Mon second fichier_2 dont le nombre de champs est variable aussi mais il est forcément égal au nombre de champs du fichier_1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    VAL1_1|VAL1_2|VAL1_3|..........|VAL1_N
    VAL2_1|VAL2_2|VAL2_3|..........|VAL2_N
    VAL3_1|VAL3_2|VAL3_3|..........|VAL3_N
    Mon objectif est d'obtenir ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CHAMP1_1|VAL1_1|CHAMP1_2|VAL1_2|CHAMP1_3|VAL1_3......|CHAMP_1_N|VAL1_N
    CHAMP1_1|VAL2_1|CHAMP1_2|VAL2_2|CHAMP1_3|VAL2_3......|CHAMP_1_N|VAL2_N
    CHAMP1_1|VAL3_1|CHAMP1_2|VAL3_2|CHAMP1_3|VAL3_3......|CHAMP_1_N|VAL3_N
    En réalité, dans le fichier_1, j'ai ma liste de champs et dans le second fichier_2, les valeurs associées à cette liste de champs.
    Un poil plus compliqué mais pas vraiment plus...

    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    paste fichier1 fichier2 -d\| |awk -F\| '{for (i=1; i <= NF/2; i++) printf("%s|%s|", $i, $(i+NF/2)); printf("\n");}' |sed -e "s/|$//"
    Explication
    Le paste va te coller chaque ligne du fichier1 au fichier 2 en les séparant par un pipe (le délimiteur interne de tes fichiers).
    Le résultat va être envoyé à un awk qui utilisera le pipe pour séparer les champs. Donc si chaque fichier a 5 champs, le awk en recevra 10 (ce nombre étant récupérable par la variable "NF" "Number of Fields")
    Ensuite il lui suffit de demander d'afficher le champ 1 avec le champ 6, le champ 2 avec le champ 7 et etc jusqu'à 5 donc en fait faire une boucle sur i allant de 1 à NF/2 et d'afficher le champ "i" suivi du champ "i+NF/2". Puis en final une petite fin de ligne.
    Comme cette boucle affiche un pipe à chaque couple de champs, la ligne se termine donc par un pipe inutile. J'aurais pu complexifier le code awk pour qu'il gère le cas particulier du dernier champ mais je préfère envoyer ça à sed pour lui demander de supprimer ce pipe final. Je te dis ça parce que d'autres préfèrent éviter les chainages de commandes quand c'est possible et que leurs choix est tout aussi respectable (surtout que dans ce cas ce n'aurait pas été très difficile de le faire faire par awk)

    Tu devrais te familiariser avec la commande awk. Elle est vraiment puissante quand il faut manipuler un fichier texte de façon un poil complexe...

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 593
    Points : 19 471
    Points
    19 471
    Par défaut
    je n'ai pas testé, mais, a priori, ça devrait fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/bash
     
    IFS='|' read -a ar1 < fic_1
     
    while IFS='|' read -a ar2
    do
       for i in ${!ar1[@]}
       do  
          printf '%s|%s' "${ar1[i]}" "${ar2[i]}"
       done
       echo
    done < fic_2
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F'|' 'BEGIN{getline < "fic_1"; split($0,a,"|")}{for(i=1;i<=NF;i++)printf("%s|%s",a[i],$i);print ""}' fic_2

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 728
    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 728
    Points : 31 050
    Points
    31 050
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    je n'ai pas testé, mais, a priori, ça devrait fonctionner :
    Les deux fonctionnent sauf qu'aucun des deux ne positionne le pipe nécessaire entre le champ pair du couple x et le champ impair du couple x+1

    Dans le premier code, il faut rectifier par ceci printf '%s|%s|' "${ar1[i]}" "${ar2[i]}" et dans le second par cela printf("%s|%s|",a[i],$i). Ensuite, il faut bien entendu trouver un moyen pour soit supprimer le dernier pipe de la ligne (typiquement un boulot pour sed) soit ne pas le mettre (rajouter par exemple le pipe en tant qu'élément variable du awk et ne pas l'afficher quand i vaut NF).

    Ceci dit, sincèrement, tu ne trouves pas que le mien est quand-même un peu plus lisible ???

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 593
    Points : 19 471
    Points
    19 471
    Par défaut
    Ceci dit, sincèrement, tu ne trouves pas que le mien est quand-même un peu plus lisible ???
    non (désolé), du awk dans un pipe ou tout seul, ça reste du awk

    merci pour la rectification, cependant je ne piperai pas awk vers du sed, car awk peut effectuer des substitutions.

  9. #9
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 310
    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 310
    Points : 12 818
    Points
    12 818
    Par défaut
    Bonjour,
    Pour le fun, ma version awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F\| '{c="";for(i=1;i<=NF;i++) if(NR == FNR) {a[i]=$i} else {b=c a[i]"|"$i;c=b"|";}};{$0=b}b' fichier1 fichier2
    Je la trouve très lisible....

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 32
    Points : 23
    Points
    23
    Par défaut
    Merci messieurs et vraiment chapeau ! Vous êtes de vrais artistes. Grâce à vous, on voit bien la puissance de awk & Co.
    Merci encore.

  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 728
    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 728
    Points : 31 050
    Points
    31 050
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Pour le fun, ma version awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F\| '{c="";for(i=1;i<=NF;i++) if(NR == FNR) {a[i]=$i} else {b=c a[i]"|"$i;c=b"|";}};{$0=b}b' fichier1 fichier2
    Tain ça marche mais j'y panne que dalle
    Je devine vaguement qu'au lieu de traiter les deux fichiers joints tu les traites en séquentiel et donc au lieu d'associer le champ x et le champ x+p (p étant le nombre de champs) tu associes la ligne x et la ligne x+q (q étant le nombre de lignes) donc en fait tu recrées un paste mais là s'arrête ma compréhension (surtout avec ces b=c puis c=b)...

    Bon, allez, +1 parce que j'y ai presque rien compris

  12. #12
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 310
    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 310
    Points : 12 818
    Points
    12 818
    Par défaut
    En fait le principe est simple (cela ressemble beaucoup à la méthode de N_BaH):
    Dans la boucle for:
    Si c'est le premier fichier, je mets chaque champs dans un tableau indicé par le numéro du champs.
    Sinon je fabrique la chaine à afficher à l'aide des variable b et c en m'arrangeant pour que b soit en retard sur le séparateur de champs final.
    En sorti de boucle, on initialise $0 avec b et en même temps on utilise b pour dire à awk d'afficher $0 et comme b n'est initialisé que dans le else, awk n'affichera pas le premier fichier.

    Cela pourrait être sympathique de proposer un solution en une seule commande sed ...

  13. #13
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 310
    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 310
    Points : 12 818
    Points
    12 818
    Par défaut
    Bon, comme personne ne veut si coller (même par jeu), voici une version sed:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ cat fic1
    CHAMP1_1|CHAMP1_2|CHAMP1_3|CHAMP_1_N
    $ cat fic2
    VAL1_1|VAL1_2|VAL1_3|VAL1_N
    VAL2_1|VAL2_2|VAL2_3|VAL2_N
    VAL3_1|VAL3_2|VAL3_3|VAL3_N
    $ sed -n '1{s/$/|/g;x;};2,${s/^\||/@/g;G;:bb;s/@\([^@]*\)\([^\n]*\n\)\([^|]*|\)/|\3\1\2/;tbb;s/^.\|\n//g;p;}' fic1 fic2
    CHAMP1_1|VAL1_1|CHAMP1_2|VAL1_2|CHAMP1_3|VAL1_3|CHAMP_1_N|VAL1_N
    CHAMP1_1|VAL2_1|CHAMP1_2|VAL2_2|CHAMP1_3|VAL2_3|CHAMP_1_N|VAL2_N
    CHAMP1_1|VAL3_1|CHAMP1_2|VAL3_2|CHAMP1_3|VAL3_3|CHAMP_1_N|VAL3_N
    Seul restriction: en plus du séparateur "|" , un autre caractère interdit ici est le "@" .

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 271
    Points : 13 536
    Points
    13 536
    Par défaut
    Bonjour,

    Dommage qu'il y ait N champs. S'il y en avait 4 fixes (ou moins), on aurait pu utiliser les références arrières.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ sed '1{h;d};2,${G;s/\n/|/;s/\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)/\5|\1|\6|\2|\7|\3|\8|\4/}' fic1.txt fic2.txt 
    CHAMP1_1|VAL1_1|CHAMP1_2|VAL1_2|CHAMP1_3|VAL1_3|CHAMP_1_N|VAL1_N
    CHAMP1_1|VAL2_1|CHAMP1_2|VAL2_2|CHAMP1_3|VAL2_3|CHAMP_1_N|VAL2_N
    CHAMP1_1|VAL3_1|CHAMP1_2|VAL3_2|CHAMP1_3|VAL3_3|CHAMP_1_N|VAL3_N

  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 728
    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 728
    Points : 31 050
    Points
    31 050
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ sed -n '1{s/$/|/g;x;};2,${s/^\||/@/g;G;:bb;s/@\([^@]*\)\([^\n]*\n\)\([^|]*|\)/|\3\1\2/;tbb;s/^.\|\n//g;p;}' fic1 fic2

    A tes souhaits

  16. #16
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 310
    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 310
    Points : 12 818
    Points
    12 818
    Par défaut
    Ok, donnons une petite explication, donc voici une version commenter du script sed (sed -n -f script.sed fic1 fic2):

    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
    1{ # Bloc a traiter pour la premiere ligne (donc ici, la ligne du premier fichier)
    	s/$/|/g #Rajout d'un "|" en fin de ligne ( "CHAMP1_1|CHAMP1_2|CHAMP1_3|CHAMP_1_N" devient "CHAMP1_1|CHAMP1_2|CHAMP1_3|CHAMP_1_N|")
    	x # on swap les buffer (ici on aurait aussi pu utiliser la commande 'h')
    } # fin du bloc de traitement de la premiere ligne
    2,${ # Bloc a traiter de la ligne 2 a la derniere ligne (donc ici, le deuxieme fichier)
    	s/^\||/@/g #Rajout d'un "@" en début de ligne et remplacement des "|" par des "@" 
    		   #"VAL1_1|VAL1_2|VAL1_3|VAL1_N" devient "@VAL1_1@VAL1_2@VAL1_3@VAL1_N"
    	G #On rajoute le buffer tampon a la fin du buffer de travail (donc la ligne 1 apres la ligne en cours):
    	  #@VAL1_1@VAL1_2@VAL1_3@VAL1_N
    	  #CHAMP1_1|CHAMP1_2|CHAMP1_3|CHAMP_1_N|
    	:bb #Etiquette de boucle
    		s/@\([^@]*\)\([^\n]*\n\)\([^|]*|\)/|\3\1\2/
    		#@\([^@]*\) => @VAL1_1 et donc Ref1 => VAL1_1
    		#\([^\n*\n\) => Ref2 => @VAL1_2@VAL1_3@VAL1_N\n
    		#\([^|]*|\) => Ref3 => CHAMP1_1|
    		#que l'on transforme en |\3\1\2 => |CHAMP1_1|VAL1_1@VAL1_2@VAL1_3@VAL1_N\n
    		#donc au final, on a |CHAMP1_1|VAL1_1@VAL1_2@VAL1_3@VAL1_N\nCHAMP1_2|CHAMP1_3|CHAMP_1_N| 
    	tbb # On retourne a :bb tant que la commande "s" est vrai, et donc a la fin de la boucle, on a:
    	    # |CHAMP1_1|VAL1_1|CHAMP1_2|VAL1_2|CHAMP1_3|VAL1_3|CHAMP_1_N|VAL1_N\n
    	s/^.\|\n//g #ici on retire le "|" du début et le "\n"
    	p # on affiche
    } #Fin du bloc de traitement de la ligne 2 a la derniere

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 728
    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 728
    Points : 31 050
    Points
    31 050
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Ok, donnons une petite explication...
    Ouais en plus en testant ton sed je viens de me rendre compte que j'avais mal lu le besoin initial.

    J'avais compris que fic1 et fic2 avaient exactement le même nombre de lignes, style ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ cat fic1
    CHAMP1_1|CHAMP1_2|CHAMP1_3|CHAMP1_4
    CHAMP2_1|CHAMP2_2|CHAMP2_3|CHAMP2_4
    CHAMP3_1|CHAMP3_2|CHAMP3_3|CHAMP3_4
     
    $ cat fic2
    VAL1_1|VAL1_2|VAL1_3|VAL1_4
    VAL2_1|VAL2_2|VAL2_3|VAL2_4
    VAL3_1|VAL3_2|VAL3_3|VAL3_4
    Et j'avais écrit mon awk en fonction. Alors qu'en fait, fic1 n'a qu'une seule ligne qu'on doit répéter pour chaque ligne de fic2. Et là, mon script ne fonctionne pas du tout (étonnant que personne ne l'ai remarqué ?) tandis que le tien (et aussi celui de N_Bah), bien évidemment, répondent parfaitement au besoin.

    Bon bref voilà quoi...

  18. #18
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 310
    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 310
    Points : 12 818
    Points
    12 818
    Par défaut
    Bah, j'avoue que j'ai lu rapidement ta solution qui comportait un paste (que je comprends mieux du coup) un awk et un sed, ce qui me semblait bien compliqué.
    Et mon but du départ était de trouver une solution avec uniquement awk mais sans passer par une boucle explicite comme for ou while (ce que je n'ai pas réussi à trouver ).
    Mais si le sujet avait été ce que tu pensais, j'avoue que je ne vois pas trop comment le faire en une seule commande sed
    Si quelqu'un a une idée de comment faire, je suis preneur

  19. #19
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Dommage qu'il y ait N champs. S'il y en avait 4 fixes (ou moins), on aurait pu utiliser les références arrières.
    Si le nombre de champs est le même pour toutes les lignes, il suffit de compter le nombre de champs dans la première ligne (si le fichier n'est pas vide) puis de construire la regexp qui va bien en se basant sur ton modèle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ sed '1{h;d};2,${G;s/\n/|/;s/\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)/\5|\1|\6|\2|\7|\3|\8|\4/}' fic1.txt fic2.txt
    C'est tellement trivial que c'est laissé en exercice au lecteur...

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

Discussions similaires

  1. [XL-2013] Copier cellules en ligne dans une colonne qui se trouve dans un autre classeur
    Par Wushugringo dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 20/02/2015, 08h07
  2. Réponses: 2
    Dernier message: 26/03/2013, 13h43
  3. [XL-2003] Sélectionner une liste dans une colonne et la reporter dans un autre fichier
    Par bentor22 dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 29/01/2013, 14h22
  4. Réponses: 2
    Dernier message: 23/11/2012, 16h20
  5. [Toutes versions] Copier une colonne d'un fichier Excel dans un fichier TEXT.
    Par jerem_orga dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 21/08/2010, 23h41

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