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] Traitement par ligne je bl_AWK


Sujet :

Shell et commandes GNU

  1. #1
    Membre actif
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Points : 292
    Points
    292
    Par défaut [awk] Traitement par ligne je bl_AWK
    Bonjour,

    j'ai du mal a comprendre la manière dont est traité un fichier texte par la commande awk.

    Pour être plus précis je souhaiterais faire un traitement différent par ligne mais cela ne fonctionne pas...

    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #!/bin/bash
    #awk '{toto= $0; printf(" essai %20s\n",toto);}' $1
     
    awk '{toto= $0; printf(" essai %20s\n",toto);}{xp1= $1; yp1= $2; xp2= $3; yp2= $4; largeur = xp2 - xp1; hauteur = yp2 - yp1; surface = largeur * hauteur; printf("\nTEG dimensions (in um):\n"); printf("	Width     : %10.6f\n",largeur); printf("	Length    : %10.6f\n",hauteur); printf("	Area      : %10.6f\n\n",surface);if (largeur != 80.000000){exit 1;}}' $1

    J'injecte un fichier texte 2 lignes:
    ligne 1 ==> BMW_x1
    ligne 2 ==> -40 1320 40 78

    Par rapport au script ci-dessus je souhaiterais effectuer la partie entre les premières accolades sur la ligne 1 et pas sur la ligne 2 et la deuxième partie entre accolade faire le traitement uniquement sur la ligne 2

    Première partie entre accolade ==> {toto= $0; printf(" essai %20s\n",toto);},
    Deuxième partie ==> {xp1= $1; yp1= $2; xp2= $3; yp2= $4; largeur = xp2 - xp1; hauteur = yp2 - yp1; surface = largeur * hauteur; printf("\nTEG dimensions (in um):\n"); printf(" Width : %10.6f\n",largeur); printf(" Length : %10.6f\n",hauteur); printf(" Area : %10.6f\n\n",surface);if (largeur != 80.000000){exit 1;}}' $1,

    J'ai bien tenté des essais avec NR == 2 ou avec next, car next semblerait etre presque l'instruction idéal pour mon pb mais je n'arrive pas l'implémenter correctement.

    L'instruction next interrompt le traitement de la ligne courante et déclenche la lecture de la ligne suivante, sur laquelle le traitement intégral sera appliqué. ( la fin me dérange car je ne veux pas effectuer le traitement intégral sur la ligne 2 )

    Merci pour votre aide.
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  2. #2
    Membre actif
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Points : 292
    Points
    292
    Par défaut
    getline peut peut-etre me sauver, je lis...

    ok pour getline, si j'ajoute getline a la fin de la première accolade le tour est joué:

    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
    {toto= $0; printf(" essai %20s\n",toto);getline}
    {
    xp1= $1
    yp1= $2
    xp2= $3
    yp2= $4
    largeur = xp2 - xp1;
    hauteur = yp2 - yp1;
    surface = largeur * hauteur;
    printf("\nTEG dimensions (in um):\n");
    printf("	Width     : %10.6f\n",largeur);
    printf("	Length    : %10.6f\n",hauteur);
    printf("	Area      : %10.6f\n\n",surface);
    if (largeur != 80.000000)
    exit 1;
    }
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  3. #3
    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 376
    Points
    19 376
    Par défaut
    Bonjour,

    tu pourrais tester que le reste de la division (modulo) par 2 retourne une valeur positive, ou pas, et effectuer, en fonction, le traitement souhaité.

    edit: vous pouvez essayer en onction, mais il n'est pas dit que le traitement soit efficace.
    .
    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,

    je pense que tu as raison getline dans le cas présent est une bonne idée, du coup tu peux même faire la totalité du traitement dans un seul bloc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    awk '
    {
       printf(" essai %20s\n", $0);
       getline;
       largeur = $3 - $1;
       hauteur = $4 - $2;
       printf("\nTEG dimensions (in um):\n");
       printf("\tWidth     : %10.6f\n", largeur);
       printf("\tLength    : %10.6f\n", hauteur);
       printf("\tArea      : %10.6f\n\n", largeur * hauteur);
       if (largeur != 80.000000){
          exit 1;
       }
    }' $1

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    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 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par julien terrier Voir le message
    J'ai bien tenté des essais avec NR == 2 ou avec next, car next semblerait etre presque l'instruction idéal pour mon pb mais je n'arrive pas l'implémenter correctement.
    Avec test sur NR:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'NR == 1 {toto= $0; printf(" essai %20s\n",toto); next; } NR == 2 {xp1= $1; yp1= $2; xp2= $3; yp2= $4; largeur = xp2 - xp1; hauteur = yp2 - yp1; surface = largeur * hauteur; printf("\nTEG dimensions (in um):\n"); printf("	Width     : %10.6f\n",largeur); printf("	Length    : %10.6f\n",hauteur); printf("	Area      : %10.6f\n\n",surface);if (largeur != 80.000000){exit}}' plop
    ou bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    awk 'NR == 1 {toto= $0; printf(" essai %20s\n",toto); next; }
    NR == 2 {xp1= $1; yp1= $2; xp2= $3; yp2= $4; 
      largeur = xp2 - xp1; hauteur = yp2 - yp1; 
      surface = largeur * hauteur; printf("\nTEG dimensions (in um):\n"); 
      printf("	Width     : %10.6f\n",largeur); 
      printf("	Length    : %10.6f\n",hauteur); 
      printf("	Area      : %10.6f\n\n",surface);
      if (largeur != 80.000000){exit}}'

  6. #6
    Membre actif
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Points : 292
    Points
    292
    Par défaut
    Merci pour vos retours toujours très instructif.

    Je reviens la semaine prochaine avec de nouvelles aventures Field Separator qui ne fonctionne pas que je voudrais...

    a la semaine prochaine
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  7. #7
    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 376
    Points
    19 376
    Par défaut
    mais traiter un fichier de deux lignes avec awk, c'est pas un peu comme utiliser un marteau-pneumatique pour poser un crochet pour les clés ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Membre actif
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Points : 292
    Points
    292
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    mais traiter un fichier de deux lignes avec awk, c'est pas un peu comme utiliser un marteau-pneumatique pour poser un crochet pour les clés ?
    Un viaggo de mille millia inizia con sempre un singulo passo (lao tseu)
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  9. #9
    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 376
    Points
    19 376
    Par défaut
    c'est le premier pas de l'homme sur la lune avant d'avant lu Jules Verne.

    en shell, si tu n'as que quelques lignes à lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    { read ligne1; read ligne2;} </chemin/fichier
    après tu fais tes traitements sur chaque ligne...

    EDIT:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ { read ligne1; read l1 h1 l2 h2;} </chemin/fichier
    $ largeur=$(( l2 - l1 )) hauteur=$(( h2 - h1 ))
    $ surface=$(( largeur * hauteur ))
    $ (( largeur != 80 )) && echo "exit 1" || LC_NUMERIC=C printf 'essai: %s\n\nwidth: %10.6f\nlength: %10.6f\narea: %10.6f\n' "$ligne1" "$largeur" "$hauteur" "$surface"
    essai: BMW_x1
     
    width:  80.000000
    length: -1242.000000
    area: -99360.000000
    à condition que les données soient toutes des entiers, car le shell ne sait pas effectuer de calculs sur les nombres réels.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  10. #10
    Membre actif
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Points : 292
    Points
    292
    Par défaut
    Il y a quelque chose qui m'echappe avec le field seperator

    Code awk : 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
    #!/bin/awk -f
    {
       FS="_";
       printf(" essai %20s\n", $1);
       printf(" essai %20s\n", $2);
       getline;
       largeur = $3 - $1;
       hauteur = $4 - $2;
       printf("\nTEG dimensions (in um):\n");
       printf("\tWidth     : %10.6f\n", largeur);
       printf("\tLength    : %10.6f\n", hauteur);
       printf("\tArea      : %10.6f\n\n", largeur * hauteur);
       if (largeur != 80.000000){
          exit 1;
       }
    }

    je m'attendais a afficher BMW puis x1 mais pas du tout j'ai BMW_x1 et rien il y a quelque chose que je ne saisie pas, de plus cela impacte le traitement après getline la je comprends que je dois faire un traitement spécifique que pour la ligne 1 ou réinitialiser la variable FS?

    Merci pour votre aide.
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  11. #11
    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 376
    Points
    19 376
    Par défaut
    apparemment, l'endroit où est défini FS importe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ awk '{FS="_"; print $1}' "$fichier"
    BMW_x1
    -40 1320 40 78
    $ awk 'BEGIN{FS="_"}{print $1}' "$fichier"
    BMW
    -40 1320 40 78
    dans le premier cas, la ligne est déjà lue, et la (re)définition du field separator est sans effet. (?)
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  12. #12
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    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 276
    Points : 12 717
    Points
    12 717
    Par défaut
    Pour le FS, l'explication est que awk ne transforme pas $0 si on ne touche aucun des champs, par contre si tu modifies un des champs, alors oui, awk fera la modification:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ echo toto_titi | awk -F_ '{print}' #ici, on ne touche à rien
    toto_titi
    $ echo toto_titi | awk -F_ '{$1=$1;print}' #ici, on modifie le champs 1
    toto titi
    Pour le getline, il faut le voir un peu comme le next mais sans retourner en début de cycle, il charge une ligne et la repasse dans $0 comme une nouvelle ligne avec tout ce que cela comprends (incrément du compteur de ligne, changement de valeur des champs, du compteur de champs, etc...).
    Cordialement.

  13. #13
    Membre confirmé
    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
    Points : 539
    Points
    539
    Par défaut
    Salut,
    Ce n'est pas la bonne explication
    $ echo toto_titi | awk -F_ '{print}' #ici, on n'affiche tout
    toto_titi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ echo toto_titi | awk -F_ '{print $1}' #ici c'est bon
    toto
    printf "toto_titi\ntata_tete" | awk '{FS="_";print $1}'
    toto_titi
    tata
    Quand on passe FS en paramètre, il est dispo partout.
    Quand on fixe FS dans le corps du programme awk, il n'est dispo qu'apres l'affectation.
    Dans mon deuxième exemple :
    awk lit la première ligne.
    Il change la variable FS pour la suite.
    Cordialement.

  14. #14
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    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 276
    Points : 12 717
    Points
    12 717
    Par défaut
    oui, c'est vrai, pas clair ce que j'ai dis .
    en complément:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ printf "toto_titi\ntata_tete" | awk '{FS="_";$0=$0;print $1}'
    toto
    tata
    Ici, en modifiant $0 par lui-même, ça le redéfini, on est juste un cran au dessus par rapport à mon exemple ou je le défini avant lecture de la première ligne.
    Cordialement.

  15. #15
    Membre actif
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Points : 292
    Points
    292
    Par défaut
    Merci pour vos retours

    Donc si j'utilise un script versus une ligne de commande la section BEGIN prend tout son sens.

    CQFD:

    La section BEGIN est exécutée avant traitement du premier enregistrement des données. Elles est utilisée essentiellement pour initialiser le contexte d’exécution.

    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
    #!/bin/awk -f
    BEGIN{FS="_"}
    {
       printf(" essai %20s\n", $1);
       FS=" ";
       getline;
       largeur = $3 - $1;
       hauteur = $4 - $2;
       printf("\nTEG dimensions (in um):\n");
       printf("\tWidth     : %10.6f\n", largeur);
       printf("\tLength    : %10.6f\n", hauteur);
       printf("\tArea      : %10.6f\n\n", largeur * hauteur);
       if (largeur != 80.000000){
          exit 1;
       }
    }
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

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

Discussions similaires

  1. [awk] Joindre un champ ligne par ligne et ses attributs
    Par shadow19c dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 29/10/2013, 18h43
  2. Traitement par tranchée de ligne
    Par Victorz dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 06/02/2013, 07h16
  3. Traitement ligne par ligne, variable
    Par eZula dans le forum Shell et commandes GNU
    Réponses: 18
    Dernier message: 24/12/2007, 00h23
  4. Lire un fichier ligne par ligne avec Awk
    Par Krispy dans le forum Linux
    Réponses: 8
    Dernier message: 07/09/2006, 15h14
  5. Traitement ligne par ligne sans curseur
    Par AbyssoS dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 28/02/2006, 17h46

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