Autres fonctions

La fonction getline

La fonction getline

By ronan, 15 mai, 2012

La fonction getline permet de lire la ligne suivante du flux sans remonter au début du traitement (contrairement à next) et de lire une ligne à partir d'un fichier, de l'entrée standard ou d'un tube.

Valeur de retour :
- 1 en cas de succès
- 0 en fin de fichier
- -1 en cas d'erreur

Il ne faut pas mettre de parenthèse lors de l'appel de la fonction getline.

Syntaxe

getline [variable]
Lecture de la ligne suivante du flux.
getline [variable] < "fichier"
Lecture d'une ligne à partir d'un fichier
"commande" | getline [variable]
Lecture d'une ligne provenant du résultat d'une commande du système.

La ligne lue par getline est stockée dans la variable variable ou $0 si aucun nom de variable n'est spécifié. Le nom de fichier "-" représente l'entrée standard.

Premier exemple :

Reconstituer des phrases écrites sur plusieurs lignes et délimitées par un caractère spécifique.

Le fichier suivant contient des phrases scindées en plusieurs lignes. Le scindement est caractérisé par un anti-slash en fin de ligne.

$ cat text.txt
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \
Maecenas porttitor congue massa. \
Fusce posuere, magna sed pulvinar ultricies,purus lectus malesuada libero, \
sit amet commodo magna eros quis urna.
Nunc viverra imperdiet enim. \
Fusce est. \
Vivamus a tellus.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. \
Proin pharetra nonummy pede. Mauris et orci.
Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.
Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. \
Mauris eget neque at sem venenatis eleifend. \
Ut nonummy.
$.

Le script suivant va analyser chaque ligne du fichier et reconstituer l'intégralité des phrases grâce à la fonction getline.

$ nl script10.awk
     1  {
     2          ligne=$0
     3          # Tant que la ligne se termine par \
     4          while(ligne ~ /\\$/){
     5                  # Suppression de \
     6                  sub(/\\$/,"",ligne)
     7                  # Lecture de la ligne suivante
     8                  getline nextline
     9                  # Concatenation de ligne et nextline
    10                  ligne=ligne nextline
    11          }
    12          # Affichage de la ligne globale
    13          printf("------- Contenu de la phrase %d -------\n%s\n",++num,ligne)
    14  }
$

Exécution du script

$ awk -f script10.awk text.txt
------- Contenu de la phrase 1 -------
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies,purus lectus malesuada libero, sit amet commodo magna eros quis urna.
------- Contenu de la phrase 2 -------
Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.
------- Contenu de la phrase 3 -------
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.
------- Contenu de la phrase 4 -------
Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.
------- Contenu de la phrase 5 -------
Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget neque at sem venenatis eleifend. Ut nonummy.
$

Deuxième exemple :

Lire une entrée clavier et le contenu d'un fichier extérieur au flux courant.

Rechercher le nom d'un département dans le fichier depts2012.txt en saisissant son nom au clavier.

$ cat depts2012.txt
REGION  DEP     CHEFLIEU        TNCC    NCC     NCCENR
82      01      01053   5       AIN     Ain
22      02      02408   5       AISNE   Aisne
83      03      03190   5       ALLIER  Allier
93      04      04070   4       ALPES-DE-HAUTE-PROVENCE Alpes-de-Haute-Provence
93      05      05061   4       HAUTES-ALPES    Hautes-Alpes
...
01      971     97105   3       GUADELOUPE      Guadeloupe
02      972     97209   3       MARTINIQUE      Martinique
03      973     97302   3       GUYANE  Guyane
04      974     97411   0       LA_REUNION      La Réunion
06      976     97608   0       MAYOTTE Mayotte
$

Le script suivant demande une saisie au clavier et recherche dans le fichier précédent le nom saisi.

$ nl script11.awk
     1  BEGIN{
     2          # Boucle infinie
     3          while(1){
     4                  printf("Rechercher le nom (ctrl+d pour quitter): ")
     5                  # Lecture clavier sur l'entree standard "-"
     6                  # Arret du programme si le code retour de getline est different de 1
     7                  if((getline nom < "-") != 1) break
     8                  # Si aucun nom saisi, on recommence
     9                  if(length(nom)==0) continue
    10                  trouve="false"
    11                  # Boucle de lecture du fichier depts2012.txt
    12                  # Tant que le code retour de getline est egal a 1
    13                  while((getline < "depts2012.txt")==1){
    14                          # Comparaison faite sans tenir compte de la casse
    15                          if(tolower($5)==tolower(nom)){
    16                                  trouve="true"
    17                                  # Affichage du resultat trouve
    18                                  print $0
    19                                  # On sort de la boucle while
    20                                  break
    21                          }
    22                  }
    23                  # Fermeture du fichier
    24                  close("depts2012.txt")
    25                  # Affichage du message si le nom n'a pas ete trouve
    26                  if(trouve=="false") print nom , "n'est pas dans le fichier"
    27          }
    28          # Affichage du message avant l'arret du programme
    29          print "\nA bientot"
    30  }
$

Exécution du script

$ awk -f script11.awk
Rechercher le nom (ctrl+d pour quitter): ain
82      01      01053   5       AIN     Ain
Rechercher le nom (ctrl+d pour quitter): somme
22      80      80021   3       SOMME   Somme
Rechercher le nom (ctrl+d pour quitter):
Rechercher le nom (ctrl+d pour quitter): var
93      83      83137   2       VAR     Var
Rechercher le nom (ctrl+d pour quitter):
A bientot
$

Troisième exemple :

Utiliser getline pour lire le résulat d'une commande système.

$ nl script12.awk
     1  BEGIN{
     2          "date" | getline
     3          print "$0 = ",$0
     4          for(i=1;i<=NF;i++){
     5                  printf("$%d = %s\n",i,$i)
     6          }
     7  }
$ awk -f script12.awk
$0 =  Tue May 15 19:35:25 CEST 2012
$1 = Tue
$2 = May
$3 = 15
$4 = 19:35:25
$5 = CEST
$6 = 2012
$

Etiquettes

Judkil (not verified)

il y a 4 ans 11 mois

Bonjour

Je souhaite réaliser une jointure ou awk prendre le nom d'une ligne dans un premier fichier, le placer en champs 1 dans le fichier output,
Puis il va dans un second ficher prends les noms étendus de la première ligne, et les place en champs 2.

Voici les Input
fichier_1:
AB-00050832
AB-00058394
AB-00050862
AB-00004123

fichier_2:
AB-00050832-18....1....-8.900758
AB-00058394-10....2....-7.981418
AB-00050832-24....3....-7.634420
AB-00050862-10....4....-7.621671
AB-00004123-1.....5....-7.386272
AB-00058394-6.....6....-7.383604
AB-00050832-12...14....-7.038594
AB-00050862-6....50....-6.701126

output:
AB-00050832.....AB-00050832-18....1....-8.900758
................AB-00050832-24....3....-7.634420
................AB-00050832-12...14....-7.038594
AB-00058394.....AB-00058394-10....2....-7.981418
................AB-00058394-6.....6....-7.383604
AB-00050862.....AB-00050862-10....4....-7.621671
................AB-00050862-6....50....-6.701126
AB-00004123.....AB-00004123-1.....5....-7.386272

Il est juste important de garder l'ordre dans lequel apparaît le nom dans fichier_1. J'ai essayé avec un getline mais j'ai l'impression qu'il y a quelque chose que je n'arrive pas à débloquer.
(J'ai rajouté des points car les espaces n'étaient pas pris en compte)

Si vous avez une idée, merci beaucoup!

Bonjour,
La commande join peut répondre à votre besoin --> à voir pourquoi le champs de la jointure est à afficher deux fois !!
join - join lines of two files on a common field
Sinon, avec awk, cela donne à peu près cela:
awk 'BEGIN { while (getline < "fichier_2" )
{
T_File[$1]=$0
}
}
{ if (T_File[$1]) print T_File[$1] " "$0 }' fichier_1
# on affiche la ligne que si jointure possible --> présence du champs 1 dans les deux fichiers

ronan

il y a 4 ans 11 mois

Voici mon idée, on lit les lignes du fichier A (fichier_1) et pour chaque valeur lue, on recherche dans le fichier B (fichier_2), à l'aide de grep, la valeur en cours de lecture du fichier A.
Pour chaque ligne trouvée dans le fichier B, on affiche la valeur du fichier A suivi d'un espace et enfin la valeur du fichier B.

$ for line in $(cat A); do while read line2; do echo -n "$line "; echo "$line2"; done <<< $(grep "^$line" B); done

Je pense que ça devrait faire l'affaire

La fonction close

La fonction close

By ronan, 15 mai, 2012

La fonction close permet de fermer un fichier ou un tube de communication. Si l'appel à cette fonction est omis, les ressources sont libérées à la terminaison du script.

L'ordre de fermeture est intéressant dans les cas suivants :
- pouvoir se repositionner en début de fichier au sein du même processus (fermeture puis réouverture)
- fermer un tube de communication pour s'en servir à nouveau
- libérer les ressources au fur et à mesure des besoins (le système limite les processus, en ce qui concerne le nombre de fichiers/tubes ouverts simultanément).

Syntaxe

close("fichier")
close("commande")

Il est indispensable de fermer un fichier pour pouvoir le relire à partir du début.

Exemple :

$ nl script13.awk
     1  BEGIN {
     2          fichier = "/root/fichier1.txt"
     3          i=1
     4          while(i<=10){
     5                  print rand() > fichier
     6                  i++
     7          }
     8          # Fermeture du fichier
     9          close(fichier)
    10          while((getline<fichier)==1){
    11                  print $0
    12          }
    13  }
$ awk -f script13.awk
0.692303
0.532958
0.423364
0.484409
0.455168
0.0133607
0.554077
0.375875
0.325945
0.164046
$

Etiquettes

La fonction system

La fonction system

By ronan, 15 mai, 2012

La fonction system permet d'exécuter une commande du système.

Syntaxe

system("commande")

La fonction retourne le statut renvoyé par la commande.

Exemple :

$ awk 'BEGIN{system("uptime")}'
 21:06:15 up 5 days,  2:22,  0 users,  load average: 0.00, 0.00, 0.00
$

Idem mais en se servant d'une variable

$ awk 'BEGIN{fic="depts2012.txt";system("ls -l " fic)}'
-rw-r--r-- 1 root root 3504 May 10 14:05 depts2012.txt
$

Etiquettes