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
$
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
$
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
$