Chrooter apache
Matériel
Ajout disque dur
Ajout carte
Audit des disques durs
Gestion des peripheriques
Disquette d'installation
Ajout d'un scanner
Graver en ligne de commande
Astuces
Ajout d'une imprimante
Réseau
Configuration reseau
Dns
Serveur cvs
Proxy squid 
Installation serveur ftp
Installation qmail 
Installation serveur courrier sous debian
Outil TCP/IP 
Le serveur samba
Connexion a distance securisee
Client/serveur vnc
Configurer apache
Dyndns
Sécurité
Chiffrer un fichier/dossier
Securiser son poste
Mur pare feu pas a pas
Authentification ht-access
Surveillance de serveur CACTI
Snort
Snort-inline
Securiser Apache avec mod_security
Filtrage squid/squidguard/dansguardian
Auditer son site web
Sécuriser son linux
Installer un Lamp avec ssl
Contrer les scans de ports
Traitement anti-spam
Installer/Utiliser tripwire
Faire des sauvegardes incrémentales
Divers
Utilisation de lilo
Les commandes Linux
Le multi-tache
Le crontab
Exploration de la configuration
Quotas
Messagerie
Installer une application
Debugger ses applications
Le format RPM
Mise a jour du noyau
Qemu
Tour d'horizon des principaux p2p
Récupération du système
Bips d'un pc
Astuces windows
Table Ascii
Lamerland
Conversion de fichiers musicaux
Compiler ses rpms
Liens
hakin9
Secureroot.com
Hackerthreads.org
Defcon
Hackerlounge
Les derniers exploits
Tous les codes sources
Securite sous Linux
Les logiciels libres quotidiens
Ezine divers
Madchat
Textes divers
Archives
 
Traductions LG
Toutes les traductions
Traductions Phrack
Toutes les traductions

Il y a actuellement 4 visiteurs connectés sur le site !

Google
Introduction à (g)awk
Introduction à (g)awk

 

Présentation
Qu'est ce que c'est
exemples
Les variables
Les fonctions
Blocs
Utiliser awk
Des scripts exécutables
Des filtres en exemple
Filtre de GéoConcept© vers GRASS(GNU/GPL)
Le mot de la fin, enfin ;-)

 

Présentation


Awk est destiné à manipuler des fichiers textes. Le principe est de chercher dans des fichiers certaines lignes, ou du texte qui contient des motifs. Quand une ligne correspond à un des motifs, awk effectue certaines actions jusqu'à ce qu'il ait atteint la fin du ou des fichiers.
Quand awk est executé, vous demandez au programme awk ce qu'il va faire pour vous. Le programme contient un certain nombre de regles. (des definitions de fonction ou des fonctionnalités plus compliquées). Chaque regle indique un motif à chercher et une action à effectuer une fois le motif trouvé. Nous allons pouvoir commencer:

Qu'est ce que c'est

awk est un langage interprété, installé par défaut sur les distributions linux (au moins rh et mandrake) dans le répertoire /bin.

BEGIN Le bloc qui suit est exécuté au début du programme, une seule fois.
END Le bloc qui suit est exécuté à la fin du programme, une seule fois.
/expression régulière/ Le bloc qui suit est exécuté si les données en cours de traitement correspondent à l'expression régulière. Si vous ne connaissez pas les expressions régulières, lisez la page man egrep.
Un exemple : /^#/ Permet de selectionner les lignes commençant par un #.
expression relationnelle Le bloc qui suit est exécuté si l'expression est vraie.
Un exemple : maVariable==5
modèle && modèle Le bloc qui suit est exécuté si les deux modèles sont vérifiés.
modèle || modèle Le bloc qui suit est exécuté si au moins un des modèles est vérifié.
modèle0 ? modèle1 : modèle2 Le bloc qui suit est exécuté si les modèles 0 et 1 sont vérifiés où si le modèle2 uniquement est vérifié.
(modèle) Permet de grouper les modèles.
Un exemple : (modèle0 || modèle1) && modèle2
! modèle Le bloc qui suit est exécuté si le modèle n'est pas vérifié.
modèle1, modèle2 Le bloc qui suit est exécuté pour la partie des données en cours commençant par modèle1 et finissant par modèle2.
Un exemple : /\/\*/, /\*\// pour afficher les commentaires multilignes

Exemples

 Avec le programme

                { print $1 " moyenne " ($2 +$3)/2 }
  

et le le fichier :

               BOBY                  18 5
               ZELYNOU               6 11
               ANTIN             8 4
               BOB              16 8 15
               IZEL              16 18 12

               

on obtient comme affichage :

                BOBY moyenne 11.5
                ZELYNOU moyenne 8.5
                ANTIN moyenne 6
                BOB moyenne 12
                IZEL moyenne 17


  

De même, avec le programme

           {   print $1
               printf(" moyenne %5.2f\n",($2+$3)/2 )
           } # fin de traitement de la ligne courante

           

et le le fichier :

      BOBY                    18 5
      ZELYNOU               6 11
      ANTIN             8 4
      BOB              16 8 15
      IZEL              16 18 12



on obtient comme affichage :

              BOBY
              moyenne  11.50
              ZELYNOU
              moyenne   8.50
              ANTIN
              moyenne   6.50
              BOB
              moyenne  12.00
              IZEL
              moyenne  17.00





awk -F ":" '{ $2 = "" ; print $0 }' /etc/passwd imprime chaque ligne du fichier /etc/passwd après avoir effacé le deuxième champ
awk 'END {print NR}' fichier imprime le nombre total de lignes du fichiers
awk '{print $NF}' fichier imprime le dernier champs de chaque ligne
who | awk '{print $1,$5}' imprime le login et le temps de connexion.
awk 'length($0)>75 {print}' fichier imprime les lignes de plus de 75 caractères. (print équivaur à print $0)
# precede chaque ligne par son numéro pour ce fichier (alignement à gauche).
awk '{print FNR "\t" $0}' files*

# precede chaque ligne par son numéro Pour l'ensemble des fichiers, avec une tabulation.
awk '{print NR "\t" $0}' files*

# énumère chaque ligne d'un fichier (le nombre est à gauche, aligné à droite)
awk '{printf("%5d : %s\n", NR,$0)}'

# énumère chaque ligne du fichier, mais ecrit seulement les nombres si la ligne n'est pas vide
awk 'NF{$0=++a " :" $0};1'
awk '{print (NF? ++a " :" :"") $0}'

# compte les lignes (comme "wc -l")
awk 'END{print NR}'

# écrit la somme des champs de chaque ligne
awk '{s=0; for (i=1; i<=NF; i++) s=s+$i; print s}'

# ajoute tous les champs de toutes les lignes et affiche la somme
awk '{for (i=1; i<=NF; i++) s=s+$i}; END{print s}'

# affiche chaque ligne après avoir remplacé chaque champ par sa valeur absolue
awk '{for (i=1; i<=NF; i++) if ($i < 0) $i = -$i; print }'
awk '{for (i=1; i<=NF; i++) $i = ($i < 0) ? -$i : $i; print }'

# affiche le nombre total de champs ("mots") de toutes les lignes
awk '{ total = total + NF }; END {print total}' fichier

# affiche le nombre total de lignes qui contiennent "Beth"
awk '/Beth/{n++}; END {print n+0}' fichier

# affiche le premier champ le plus grand et la ligne qui le contient
awk '$1 > max {max=$1; maxline=$0}; END{ print max, maxline}'

# affiche le nombre de champs de chaque ligne, suivi par la ligne
awk '{ print NF ":" $0 } '

# affiche le dernier champ de chaque ligne
awk '{ print $NF }'

# affiche le dernier champ de la dernière ligne
awk '{ field = $NF }; END{ print field }'

# affiche toutes les lignes de plus de quatre champs
awk 'NF > 4'

# affiche toutes les lignes dans lesquelles la valeur du dernier champ est supèrieure à 4
awk '$NF > 4'

# crée une chaine d'une certaine longueur (c'est-à-dire avec 513 espaces)
awk 'BEGIN{while (a++<513) s=s " "; print s}'

# insére une chaine d'une certaine longueur à une certaine position de caractère
# Exemple: insére 49 espaces après la colonne 6 de chaque ligne en entrèe.
gawk --re-interval 'BEGIN{while(a++<49)s=s " "};{sub(/^.{6}/,"&" s)};1'

# crée un tableau nommé month, indexé par des numéros afin que month[1]
# soit 'Jan', month[2] 'Feb', month[3] 'Mar' et ainsi de suite.
split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", month, " ")

# crée un tableau appelé "mdigit", indexé par des chaines, afin que
# mdigit["Jan"] soit 1, mdigit["Feb"] 2, etc. Necessite un tableau "month"
for (i=1; i<=12; i++) mdigit[month[i]] = i

# Dans un environnement UNIX, convertit des lignes DOS (CR/LF) en format Unix
awk '{sub(/\r$/,"")};1' # suppose que chaque ligne finit par Ctrl-M

# Dans un environnement UNIX convertit des lignes Unix (LF) en format DOS
awk '{sub(/$/,"\r")};1'

# Dans un environnement DOS convertit des lignes Unix (LF) en format DOS
awk 1

# Dans un environnement DOS convertit des lignes DOS (CR/LF) en format Unix
# Ne peut être fait avec les versions DOS de awk, autres que gawk:
gawk -v BINMODE="w" '1' infile >outfile

# supprimer les espaces principaux (espaces, tabulations) au début de chaque ligne
awk '{sub(/^[ \t]+/, "")};1'

# supprime les espaces finaux (espaces, tabulations) de la fin de chaque ligne
awk '{sub(/[ \t]+$/, "")};1'

# supprime les espaces au début et à la fin de chaque lignes
awk '{gsub(/^[ \t]+|[ \t]+$/,"")};1'
awk '{$1=$1};1' # supprime également des espaces supplémentaires entre les champs

# insére cinq espaces vides au début de chaque ligne (fait une page de décalage)
awk '{sub(/^/, " ")};1'

# aligne le texte à droite avec une largeur de 79-colonnes
awk '{printf "%79s\n", $0}' fichier*

# centre le texte avec une largeur de 79-caractères
awk '{l=length();s=int((79-l)/2); printf "%"(s+l)"s\n",$0}' fichier*

# remplace (trouve et remplace) "foo" par "bar" dans chaque ligne
awk '{sub(/foo/,"bar")}; 1' # remplace seulement la première occurence
gawk '{$0=gensub(/foo/,"bar",4)}; 1' # remplace seulement la quatrième occurence
awk '{gsub(/foo/,"bar")}; 1' # remplace toutes les occurences de la ligne

# remplace "foo" par "bar" seulement pour les lignes qui contiennent "baz"
awk '/baz/{gsub(/foo/, "bar")}; 1'

# remplace "foo" par "bar" sauf pour les lignes qui contiennent "baz"
awk '!/baz/{gsub(/foo/, "bar")}; 1'

# modifie "scarlet" ou "ruby" ou "puce" en "red"
awk '{gsub(/scarlet|ruby|puce/, "red")}; 1'

# inverser l'ordre des lignes (comme avec "tac")
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' fichier*

# si une ligne se finit par un backslash, ajoutez la ligne suivante à celui-ci (cela échoue si il y a plusieurs lignes
#finissant par un backslash...)
awk '/\\$/ {sub(/\\$/,""); getline t; print $0 t; next}; 1' fichier*

# affiche et trie les noms de login de tous les utilisateurs
awk -F ":" '{print $1 | "sort" }' /etc/passwd

# affiche les deux premiers champs, en ordre inverse de chaque ligne
awk '{print $2, $1}' file

# échange les deux premiers champs de chaque ligne
awk '{temp = $1; $1 = $2; $2 = temp}' fichier

# affiche chaque ligne, en supprimant le second champ de cette ligne
awk '{ $2 = ""; print }'

# affiche dans l'ordre inverse les champs de chaque ligne
awk '{for (i=NF; i>0; i--) printf("%s ",$i);print ""}' file

# concatene toutes les 5 lignes en entrée, en employant un séparateur virgule
# entre les champs
awk 'ORS=NR%5?",":"\n"' file

# affiche les 10 premières lignes du fichier (émule le comportement de la commande "head")
awk 'NR < 11'

# affiche la première ligne du fichier (émule "head -1")
awk 'NR>1{exit};1'

# affiche les deux dernières lignes d'un fichier (émule "tail -2")
awk '{y=x "\n" $0; x=$0};END{print y}'

# affiche la dernière ligne d'un fichier (émule "tail -1")
awk 'END{print}'

# affiche seulement les lignes qui correspondent à une expression régulière (émule "grep")
awk '/regex/'

# affiche seulement les lignes qui ne correspondent pas à une expression régulière (émule "grep -v")
awk '!/regex/'

# affiche toutes les lignes où le champ #5 est égal à "abc123"
awk '$5 == "abc123"'

# affiche seulement les lignes où le champ #5 n'est pas égal à "abc123"
# cela affichera aussi les lignes qui ont moins de 5 champs.
awk '$5 != "abc123"'
awk '!($5 == "abc123")'

# correspondance avec un champ à l'aide d'une expression régulière
awk '$7 ~ /^[a-f]/' # affiche la ligne si le champ #7 correspond à l'expression régulière
awk '$7 !~ /^[a-f]/' # affiche la ligne si le champ #7 ne correspond pas à l'expression régulière

# affiche la ligne immédiatement avant une expression, mais pas la ligne contenant l'expression
awk '/regex/{print x};{x=$0}'
awk '/regex/{print (NR==1 ? "match on line 1" : x)};{x=$0}'

# affiche la ligne immédiatement après l'expression, mais pas la ligne contenant l'expression
awk '/regex/{getline;print}'

# fait une recherche avec grep pour AAA et BBB et CCC (dans n'importe quel ordre sur la même ligne)
awk '/AAA/ && /BBB/ && /CCC/'

# fait une recherche avecc grep pour AAA et BBB et CCC (dans cet ordre)
awk '/AAA.*BBB.*CCC/'

# affiche seulement des lignes de 65 caractères ou plus
awk 'length > 64'

# affiche seulement des lignes de moins de 65 caractères
awk 'length < 64'

# affiche la partie du fichier depuis l'expression régulière jusqu'à la fin du fichier
awk '/regex/,0'
awk '/regex/,EOF'

# affiche la partie du fichier basée sur les numéros de ligne (lignes 8-12, inclus)
awk 'NR==8,NR==12'

# affiche la ligne numéro 52
awk 'NR==52'
awk 'NR==52 {print;exit}' # plus efficace avec de gros fichiers

# affiche une partie d'un fichier entre deux expressions régulières (inclus)
awk '/Iowa/,/Montana/' # sensible à la casse

# supprimer toutes les lignes vides d'un fichier (même chose que "grep '.' ")
awk NF
awk '/./'

# supprime des doublons et des lignes consécutives (émule "uniq")
awk 'a !~ $0; {a=$0}'

# supprime les doublons et les lignes non-consécutives
awk '!a[$0]++' # script plus concis
awk '!($0 in a){a[$0];print}' # script plus efficace

Les variables

Voici la liste des variables prédéfinies en awk.
ARGC Cette variable contient le nombre d'arguments passés au programme. (sans les options passées à awk)
ARGV Nombre d'arguments de la ligne de commande.
CONVFMT Le format par défaut pour l'affichage des nombres, "%.6g" par défaut
ENVIRON Un tableau contenant les variables d'environnement. Exemple ENVIRON["PATH"] contient votre path.
FIELDWIDTHS Pour le cas de traitement de données non délimités mais contenant des champs de largeur fixe.
Cette variable est de la forme largeur_champ_1 largeur_champ_2 largeur_champ_3 etc....
FNR Le numéro de l'enregistrement actuellement en cours de traitement.
Un exemple : awk '{print FNR ": " $0}' un_fichier permet d'afficher le fichier avec les numéros de lignes.
Un autre exemple : awk '{print FNR ": " $0}' un_fichier | grep ^45: permet d'afficher la ligne 45 du fichier un_fichier. On fait appel à grep, ce n'est plus du 100% awk mais c'est beau la diversité, non ?
FS Le séparateur de champs. No comment !
IGNORECASE En gros, permet de ne pas prendre en compte la casse lors des comparaisons de chaines de caractères entre elles où avec des expressions régulières. Voir la page de manuel pour les détails.
NF nombre de champs de l'enregistrement courant.
NR nombre d'enregistrements deja lu.
RS separateur d'enregistrement en entrée

Bien entendu, vous pouvez également définir les vôtres.

Exemples :
maVar=3 déclare et initialise la variable myVar à la valeur 3.
print maVar affiche le contenu de la variable maVar.
print $maVar affiche le champ n°maVar de l'enregistrement en cours (ici, équivaut à print $3).
print $(maVar-1) affiche le champ n°(maVar-1) de l'enregistrement en cours (ici, équivaut à print $2).
split("toto:tata:titi:tutu", arr, ":") initialise le tableau arr à ("toto","tata",...). On accède ensuite aux valeurs par arr[1], arr[2], ..., arr[4]

Les fonctions

l y en a de nombreuses :

* pour l'affichage formaté, de textes et de nombres. print printf ...
* pour les opérations habituelles sur les chaines de caractères, concaténation, substitution, remplacement, recherche ... gensub substr tolower index split ...
* pour les accés aux systèmes de fichiers et au système fflush close nextline system
* pour les fonctions mathématiques rand sin exp log ...
* pour la gestion du temps systime strftime
Les possibilités de formatage importantes à votre disposition sont définies dans la page de manuel de awk.
Et vous pouvez également définir vos fonctions grâce à la syntaxe : function nom_de_fonction(param1, param2, var_locale_1, var_locale_2) {
...
...
}
ou func nom_de_fonction(param1, param2 var_locale_1, var_locale_2) {
...
...
}
Voici un tableau des fonctions numeriques:
Nom des fonctions signification
atan2(y,x) arctangente de x/y en redians dans l'interval -pi pi
cos(x) cosinus (en radians)
exp(x) exponentielle e à la puissance x
int(x) valeur entière
log(x) logarythme naturel
rand() nombre aléatoire entre 0 et 1
sin(x) sinus (en radians)
sqrt(x) racine carrée
srand(x) reinitialiser le générateur de nombre aléatoire
Les fonctions sur les chaines de caractères
Dans le tableau suivant :
s et t represente des chaines de caractères
r une expression régulière
i et n des entiers
Nom des fonctions signification
gsub(r,s,t) sur la chaine t, remplace toutes les occurance de r par s
index(s,t) retourne la position la plus à gauche de la chaine t dans la chaine s
length(s) retourne la longueur de la chaine s
match(s,r) retourne l'index ou s correspond à r et positionne RSTART et RLENTH
split(s,a,fs) split s dans le tableau a sur fs, retourne le nombre de champs
sprintf(fmt,liste expressions) retourne la liste des expressions formattée suivant fmt
sub(r,s,t) comme gsub, mais remplce uniquement la première occurence
substr(s,i,n) retourne la sous chaine de s commencant en i et de taille n

Blocs

Utilisation des blocs

Prenons un exemple :
#!/usr/bin/awk -f
BEGIN {
print "début du script"
maVariable=5
nbLignes=0
nbCommentaires=0
nbCommentaires2=0
print "maVariable vaut " maVariable
}
( /^#/ || /^$/ ) {
nbCommentaires++
}
{
nbLignes++
printf "%04d:%s\n",FNR,$0
if ( $0 ~ /^#/ || $0 ~ /^$/ )
nbCommentaires2++
}
}
END {
print "fin du script maVariable vaut toujours " maVariable
print "Le script a traité " FNR " lignes dont " nbCommentaires "(="co mmentaires2 ") lignes vides ou commençant par un #"
}
Explications :

* Le bloc BEGIN est exécuté une fois au début, avant le traitement des données. Il affiche "début du script", initialise les variables et affiche le contenu de maVariable.
* Un bloc qui est exécuté pour chaque ligne commençant par un # ou vide, il incrémente la variable nbCommentaires.
* Un Bloc exécuté pour toutes les lignes, il incrémente la variable nbLignes, affiche la ligne préfixée par son numéro. Le numéro est formaté pour occupper quattre caractères. Les lignes suivantes (à partir du if) montrent l'équivalence entre le bloc du dessus et un test if dans le bloc principal. La variable nbCommentaires2 est incrémentée pour chaque ligne commençant par un dièse ou vide.
* Le bloc END est exécuté une fois à la fin, après le traitement des données. On voit que la variable maVariable est toujours définie et que son contenu n'a pas été altéré. Il indique également le nombre total de lignes traitées et le nombre de lignes de commentaires ou vides présentes dans le fichier.
Exécution
br> # chmod a+x ceScript.awk
# ./ceScript.awk unfichier.shell
début du script
maVariable vaut 5
0001:# Ce script affiche hello world
0002:
0003:echo "hello world"
0004:exit 0
fin du script maVariable vaut toujours 5
Le script a traité 4 lignes dont 2(=2) lignes vides ou commençant par un #

Utiliser awk

Par la ligne de commande

La structure de base de l'utilisation de awk à partir de la ligne de commande est la suivante:
awk [programme|-f fichierdecommandes] [options/variables] [fichiers] Le premier argument peut être une commande awk, une série de commandes séparées par des points-virgules, ou bien encore un fichier contenant une série de commandes awk. S'il faut spécifier un fichier de commandes, vous devez utiliser l'option -f.
Les arguments suivants sur la ligne de commande sont les options ou les déclarations de variables. Si vous utilisez -F re, l'expression régulière re remplit le rôle de séparateur de champ à la place de "l'espace vide" par défaut. Pour initialiser des variables, saisissez variable =VALEUR dans la ligne de commande. Terminez par énumérer les fichiers d'entrée. .

Des scripts exécutables

Pour des exemples simples de awk à l'intérieur de scripts shell, je vous renvoie sur : http://abs.traduc.org/abs-3.2-fr/awk.html

Des filtres en exemple

Transformer le fichier hosts

. Voici donc le code du premier filtre exemple :
#!/usr/bin/awk -f
!(/^#/ || /^$/) {
split ($1, array_ip, ".")
printf "%03d.%03d.%03d.%03d\t%s\t%s\n", array_ip[1], array_ip[2], array_ip[3], array_ip[4],$2,$3
}

La première ligne signifie qu'on va chercher awk dans le répertoire /usr/bin/, ce qui est le bon chemin pour ma slack.
La deuxiême ligne signifie qu'on ne s'intéresse qu'aux lignes qui ne commencent pas par un # ni aux lignes vides. En effet en expressions régulières, ^ signifie début de chaîne et $, fin de chaîne.
Par la suite, on découpe le premier paramètre en prenant comme séparateur le ., on stocke le résultat dans un tableau et on affiche les données du tableau en les formattant puis les autres champs (nom_de_machine et nom_de_machine.domaine). Le formatage %03d signifie qu'on affiche des entiers sur trois caractères et que s'il manque des caractères, on précède ceux qui existent avec des 0.
Il faut rendre ce script exécutable : chmod a+x prepare_hosts.awk
Puis, on l'appelle comme ça : ./prepare_hosts.awk /etc/hosts > hosts.prepared pour récupérer le fichier traité dans un fichier hosts.prepared placé dans le répertoire en cours.
.

Sources de l'article


 

Forum
Forum d'entraide
Blog
Le blog
News
Les news du site
Php/Mysql
Formulaire en php
Administrer un serveur Mysql
Session en php
Gerer ses bases mysql
Les bases php
Securiser ses scripts PHP
Controler ses programmes avec RATS
Convertir une base sql en utf8
Astuces php
Programmation
Python rapide
Tutorial Python
Tutorial Perl
Tutorial Perl complet
Tutoriel ruby
Tutoriel C
Introduction à gawk
Filtres et utilitaires
Find
Programmation Shell
Ecriture de scripts bash
Expressions regulieres
Vi
Introduction a Javascript
Compiler avec gcc
Astuces en Bash
Cracking
Tutoriel Assembleur
Guide du cracking pour débutant
Assembleur
Manual Unpacking
Techniques de Protection
Différentes failles Web
Arp spoofing dans un réseau switché
Les intrusions
Les attaques externes
Defacage
Defacage complet
Buffer overflow
Netcat
Injection sql
Injection sql(suite)
John the Ripper
Spoofer un email
Utiliser google
La faille system
Usurper une identité
Le rooting
Shellcode sous Unix
La faille race condition
La faille xss
La faille xss (2)
Attaques sur un routeur
P2P
Azureus pas-a-pas
News
Lire les news de Linux-pour-lesnuls.com au format RSS
Distros
Gestion des paquets debian
101 commandes debian
Graphisme
Effet neon dans GIMP
Effet vapeur dans GIMP
Cours fonctionnalités de GIMP
Humour
Ensemble
Divers