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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    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
    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.

  2. #2
    Membre éclairé
    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
    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;
    }

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    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 confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

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

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    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 103
    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 103
    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 éclairé
    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
    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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    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 éclairé
    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
    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)

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    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.

+ 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