# awk : quelques notes

awk lit les lignes d'un fichier dans l'ordre. Il vérifie si la ligne répond à une condition et réalise dans ce cas des actions écrites entre ''{}'', sinon il passe à la ligne suivante.

La condition peut être un test sur une variable ''(v == 2)'', ou bien un test sur motif correspondant au texte de la ligne ''/^Debut/'' (vous avez dit regex?).
regex
Par défaut, awk affiche la ligne sur la sortie standard.

Utiliser ''END'' permet d'exécuter des commandes (entre {}) à la fin, ''BEGIN'' au début. Pratique pour définir des variables..

Exemple :

```
#!/usr/bin/awk -f
BEGIN { print "File\tOwner"}
{ print $8, "\t", $3}
END { print " - DONE -" }
```

## Variables spéciales

''NF'' : nombre de champs dans la ligne. ''$(NF-2)'' permet d'accéder à l'élément 2 rangs avant le dernier
''NR'' : numéro de ligne parsée
''FS'' : ce qui sépare 2 champs. Par défaut, c'est un espace. On le change au tout début avec ''BEGIN{FS=":"}''
''$0'' représente toute la ligne

On peut utiliser des variables sans les déclarer puis les afficher ensuite. Par défaut, une variable non initialisée contient ''""''.

## Patterns:

```
/admin/ { ... }     # any line that contains 'admin'
/^admin/ { ... }    # lines that begin with 'admin'
/admin$/ { ... }    # lines that end with 'admin'
/^[0-9.]+ / { ... } # lines beginning with series of numbers and periods
/(POST|PUT|DELETE)/ # lines that contain specific HTTP verbs
```

## Actions et fonctions

''next'' : passe à la ligne suivante sans passer par les autres tests.
''length(s)'' : longueur de la chaîne s
''gsub(r, t, s)'' : remplace par t toute occurence de l'expression régulière r dans la chaîne s.

Voir aussi le ''man'' de awk pour ''match()'', ''sub()'', ''substr()'', ...

## getline

''getline()'' permet de lire le contenu d'un autre fichier et l'enregistrer en mémoire ou bien le traiter comme la ligne courante ''$0''. Chaque nouvel appel à ''getline()'' renvoie la ligne suivante du fichier lu.

Il FAUT penser à fermer le fichier ET à vérifier que la lecture se passe bien.

Par exemple, pour enregistrer dans "var" la première ligne de "fichier.txt", on suivra la démarche suivante :

```
f = "fichier.txt"
if ((getline var < f) != 1 ) { next }
close(f)
```

On peut simuler la commande cat ainsi :

```
while ((getline < "fichier.txt") == 1) {
    print
}
close("fichier.txt")
```

## Astuces diverses

On peut combiner les tests pour un pattern et une variable. Par exemple, pour ne traîter QUE la 1ere ligne SI elle ne contient pas "absent" :

```
apm | awk 'NR==1 && !/absent/ {printf " ⚡%s", $4}'
```

On peut définir toute une série de caractères comme délimiteurs. Par exemple n'importe quelle lettre suivie de ":" :

```
uptime | awk -F'[a-z]:' '{print $2}'
```

Au lancement de awk, utiliser ''-v var=value'' permet de définir une variable. Ce flag peut être utilisé plusieurs fois.

On peut concaténer des chaînes de caractères ainsi :

```
txt1 = "Hello"
txt2 = "World"
txt = txt1 " " txt2

# txt contient "Hello World"
```

On n'est pas obligé de prendre un fichier texte ou de lire l'entrée standard. On peut aussi interpréter une liste passée en argument :

```
BEGIN {
    for ( i = 1; i <= ARGC; i++ ) {
        print ARGV[i]
    }
    exit
}
```

### trim avec awk

```
awk '{sub(/^[[:blank:]]+/, ""); sub(/[[:blank:]]+$/, ""); print }'
```

### Extraire une portion de texte situé à un index donné.

Il faut utiliser ''match()'' pour identifier l'emplacement du texte cherché (dans la variable ''RSTART'') puis utiliser ''substr()'' pour extraire la portion voulue.

Par exemple pour récupérer le pourcentage du signal wifi.

```
match($0, "[0-9]+%")
if ( RLENGTH != -1 ) {
    perc = substr($0,RSTART,RLENGTH)
}
print perc
```

### Simuler cut -f2- : afficher les colonnes suivantes

```
awk '1 {for (i = 2; i <= NF; i++;) {print $i}'
```

### Afficher ce qui est entre 2 pattern

```
awk '/PAT1/,/PAT2/' file
```

### Bien utiliser les regex

Dans sub(), gsub() ou autres, il vaut mieux éviter d'utiliser des regex entre double quotes, mais plutôt entre "/".
Exemple : 

```
gsub(/\.\.\//, "", p)
```

## Références
https://gregable.com/2010/09/why-you-should-know-just-little-awk.html
https://ferd.ca/awk-in-20-minutes.html
https://minhhh.github.io/posts/awk-tutorial
https://eradman.com/posts/awk-programming.html
---
/