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 :

[awk] Index des champs de lignes variables


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2015
    Messages : 21
    Points : 23
    Points
    23
    Par défaut [awk] Index des champs de lignes variables
    Bonjour

    j'ai un fichier qui se présente avec des lignes qui n'ont pas un NF fixe, car un des champs (le nom, ici en $3 en première ligne) est parfois composé d'espaces :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    abc  2Dtoto    nom1               2    2019aaa
    def  2Dtiti    nom2 ext           -4   2019bbb	
    ghi  2Dtutu    nom3 extA extB     3    2019ccc
    Je souhaite extraire ce nom en totalité. J'ai tenté via index, en tentant d'extraire les données entre le début du $3 et le celui de l'avant dernier champ (NF-1) moins 1 position, çad avec index et un calcul de longueur adéquate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nom = substr($0,index($0,$3),index($0,$(NF-1))-index($0,$3)-1)
    Malheureusement, ça ne marche pas pour la ligne 1 et la ligne 3 : l'index trouve l'occurrence de $(NF-1) [='2' ou '3' pour ces lignes] bien avant cette position (càd en $2 et $3 respectivement).
    Question : n'y a-t-il pas un moyen de connaitre les position dans $0 de chaque champ $i (de 1 à NF) ?

    Merci pour toute idée

  2. #2
    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 459
    Points
    13 459
    Par défaut
    Bonjour

    Déjà, es-tu bien sûr qu'il s'agit d'espaces ? Ne sont-ce pas des tabulations ?

    Ensuite, si les champs ne permettent pas de se repérer, alors, c'est que les champs commencent tous au même caractère. (ce qui semble être le cas)

    D'où la question, pourquoi awk ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ sed 's/.\{15\}//;s/[[:blank:]].*//' fichier.txt
    nom1
    nom2
    nom3
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  3. #3
    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
    la notion de champs recoupe celle de séparateur de champ.
    s'il n'y a pas de séparateur : il n'y a pas de champ.
    le séparateur par défaut de awk est l'espace, qu'importe leur nombre consécutif.
    cela implique que des espaces entourant des champs vides seront perçus par awk comme un seul espace, sans "voir" le(s) champs vide(s).

    il faut donner une structure plus rigoureuse au fichier lors de sa création.
    d'où viennent les données ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    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 fichier semble indiquer que les "colonnes" ont une taille fixe, s'il s'agit bien d'espaces en awk on peut envisager quelque chose du genre :
    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
    #!/usr/bin/awk -f
     
    BEGIN {
       # "abc  2Dtoto    nom1               2    2019aaa"
       #  ^    ^         ^                  ^    ^
       #  0    5         15                 34   39
       sep1 = 5
       sep2 = 15
       sep3 = 34
       sep4 = 39
    }
     
    {
       #  on extrait la chaine...        ...et on enleve les espaces/tabulations qui trainent
       f1 = substr($0, 0, sep1)            ; sub(/[ \t]+$/, "", f1)
       f2 = substr($0, sep1+1, sep2-sep1)  ; sub(/[ \t]+$/, "", f2)
       f3 = substr($0, sep2+1, sep3-sep2)  ; sub(/[ \t]+$/, "", f3)
       f4 = substr($0, sep3+1, sep4-sep3)  ; sub(/[ \t]+$/, "", f4)
       f5 = substr($0, sep4+1)             ; sub(/[ \t]+$/, "", f5)
     
       # on affiche
       printf("line = \"%s\"\n", $0)
       printf("f1   = \"%s\"\n", f1)
       printf("f2   = \"%s\"\n", f2)
       printf("f3   = \"%s\"\n", f3)
       printf("f4   = \"%s\"\n", f4)
       printf("f5   = \"%s\"\n", f5)
       printf("\n")
    }
    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
    18
    19
    20
    21
    $ ./script.awk fichier
    line = "abc  2Dtoto    nom1               2    2019aaa"
    f1   = "abc"
    f2   = "2Dtoto"
    f3   = "nom1"
    f4   = "2"
    f5   = "2019aaa"
     
    line = "def  2Dtiti    nom2 ext           -4   2019bbb  "
    f1   = "def"
    f2   = "2Dtiti"
    f3   = "nom2 ext"
    f4   = "-4"
    f5   = "2019bbb"
     
    line = "ghi  2Dtutu    nom3 extA extB     3    2019ccc"
    f1   = "ghi"
    f2   = "2Dtutu"
    f3   = "nom3 extA extB"
    f4   = "3"
    f5   = "2019ccc"

  5. #5
    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
    Gawk dispose d'une variable FIELDWIDTHS pour lire les fichiers à colonnes à longueur fixe.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  6. #6
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 284
    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 284
    Points : 12 739
    Points
    12 739
    Par défaut
    Pour le fun:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ cat /tmp/fic.txt 
    abc  2Dtoto    nom1               2    2019aaa
    def  2Dtiti    nom2 ext           -4   2019bbb	
    ghi  2Dtutu    nom3 extA extB     3    2019ccc
    $ awk '{NF-=2;$1=$2="";gsub(FS FS,"")}1' /tmp/fic.txt 
    nom1
    nom2 ext
    nom3 extA extB
    Cordialement.

  7. #7
    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
    c'est bÔ !!!
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2015
    Messages : 21
    Points : 23
    Points
    23
    Par défaut
    Merci à vous 2 :
    - je ne connaissais pas la variable FIELDWIDTHS, oui, elle est bien utile ! (en fait mon recueil awk date de l'année 1992, et c'est beau car écrit en LateX ...faudrait p-ê passer à nawk ou gawk apparemment )
    - le script fonctionne bien, mais je ne comprends pas cette ligne : gsub(FS FS,"") ? Pour moi, cela veut dire que tout double espace est remplacé par du vide. Ok, mais en quoi les 2 derniers champs disparaissent aussi lors du listing ?
    --> Qui peut m'éclairer ?
    (d'ailleurs je viens d'apprendre cette nouvelle syntaxe ({}1) pour print $0, sympa)


    En fait j'ai qd mm réflechi de mon côté en fin de journée, et j'ai trouvé un autre moyen :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    nb_champs_theor = 5 # si pas d'espaces dans le nom
    nom = $3
    for (k=4;k<=3+NF-nb_champs_theor;k++) {nom = nom" "$k}
    Un peu plus long mais ça marche aussi

  9. #9
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 284
    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 284
    Points : 12 739
    Points
    12 739
    Par défaut
    Pour les 2 derniers champs, c'est le NF-=2 qui dit à awk de réduire le nombre de champs (obligatoirement finaux).

    En fait, dés que l'on a pas des champs vides (surtout si le FS est l'espace), on peut supprimer un champs quelconque (sauf le dernier) par:
    Avec n le n° du champs que l'on veut supprimer. Celui-ci sera réellement supprimé car même le compteur de champs (NF) est modifié:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     $ awk '{NF-=2;print "NF avant:" NF;print;$1=$2=FS;gsub(FS FS,"");print "NF après:" NF}1' /tmp/fic.txt
    NF avant:3
    abc 2Dtoto nom1
    NF après:1
    nom1
    NF avant:4
    def 2Dtiti nom2 ext
    NF après:2
    nom2 ext
    NF avant:5
    ghi 2Dtutu nom3 extA extB
    NF après:3
    nom3 extA extB
    Cordialement.

  10. #10
    Membre à l'essai
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2015
    Messages : 21
    Points : 23
    Points
    23
    Par défaut
    autant pour moi, j'avais mal "lu" le NF-=2, en ayant en tête pour je ne sais quelle raison que c'était les 2 premiers champs qui "s'effaçaient" et non les derniers (le $1=$2="" est en effet le pendant de NF-=2 pour les colonnes de gauche)
    Thx2all

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

Discussions similaires

  1. Renseigner des champs HTML avec variable PHP sur un évenement OnChange
    Par jimmy14 dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 06/09/2015, 18h50
  2. [awk] Extraire des champs avec plusieurs séparateurs différents
    Par leon1983 dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 20/11/2013, 16h20
  3. [WD16] Indexer des champs btn
    Par akzo81 dans le forum WinDev
    Réponses: 1
    Dernier message: 21/12/2011, 22h30
  4. Réponses: 1
    Dernier message: 20/11/2007, 15h12
  5. la moyen des champs sur ligne
    Par nah_wah dans le forum MS SQL Server
    Réponses: 13
    Dernier message: 04/08/2005, 11h45

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