Table des matières

Scripts awk

Docs

Attention aux locales !!! (merci à Christophe Martin de la liste shell@asyd.net), autant pour le séparateur décimal (la virgule en fr) que les règles de collation min/maj :

echo 'Un test
une autre ligne' | env LANGUAGE=fr_FR.UTF-8 LANG=fr_FR.UTF-8 awk '/^[a-z]/'
Un test
une autre ligne
 
echo 'Un test
une autre ligne' | env LANGUAGE=C LANG=C awk '/^[a-z]/'
une autre ligne
 
echo '1.2 1,3'|env LC_ALL=fr_FR.UTF-8 awk '{print $1*10 " " $2*10}'
10 13
echo '1.2 1,3'|env LC_ALL=C awk '{print $1*10 " " $2*10}'
12 10

Donc, il vaut mieux assurer avec un alias du genre

alias awk='env LANGUAGE=C LANG=C LC_ALL=C LC_NUMERIC=C awk'

(LC_ALL devrait suffire, mais ça mange pas de pain…)

Syntaxe

Boucle for

ls -l | awk '{
  fich=$8;
  for (i=9;i<=NF;i++) {fich=fich" "$i};
  # on sort le nom du fichier avec ses espaces entre guillemets, puis date;heure;taille
  print "\""fich"\";"$6";"$7";"$5
}'

Lister les IP et le nb d'accès d'un log www

awk '{nb[$1]++} END {for (ip in nb) print ip "\t" nb[ip]}' < access.log

Ou si on veut le reverse

awk '{nb[$1]++} END {for (ip in nb) {system("/usr/bin/host " ip "|cut -d '"' '"' -f 5;print "\t" ip "\t" nb[ip]}}' < access.log

Compter les hits et afficher les heures qui dépassent un nb de hits

awk -F : '{nb[$2][$3]++} END {for (h in nb) {for (m in nb[h]) if (nb[h][m] > 9999) printf("%s:%s %d\n", h, m, nb[h][m])}}' < access.log > access.highfreq.log

Exemples

Découper un fichier

Découper un fichier avec pleins de VirtualHosts en plusieurs fichiers (un par virtualhost, du nom du ServerName)

awk 'BEGIN {new = 0} 
  /<VirtualHost/ { new = 1; fout = 0; out="";} 
  /ServerName/ { fout = $2; print out > fout;new=0;} 
  {if (new>0) { out = out "\n" $0}}
  {if (fout!=0) { print $0 > fout;new=0}}' < tous_les_virtualhosts_confondus.conf

Monitoring de processus

#!/bin/bash
NBMES=10
INTER=0.5
SLEEP_DELAY=1
PROCESS=java
 
function usage() {
  echo "usage: $(basename $0) -n <nb de mesures> -i <intervalle entre deux mesures> -s <duree d'attente avant de retester pour relancer une série> -p <process à surveiller>"
  echo "Tous les arguments sont facultatifs";
  echo "Par défaut on a $NBMES mesures, toutes les ${INTER}s avec un délai de ${SLEEP_DELAY}s entre deux tests sur le process $PROCESS"
  exit;
}
 
while getopts "n:i:s:p:h" OPTION
do
  case $OPTION in
    n ) NBMES=$OPTARG;;
    i ) INTER=$OPTARG;;
    s ) SLEEP_DELAY=$OPTARG;;
    p ) PROCESS=$OPTARG;;
    h ) usage;;
  esac
done
 
PID=''
while [ "$PID" = '' ]
do
  sleep $SLEEP_DELAY
  PID=$(pidof $PROCESS|awk '{print $1}')
  while [ "$PID" != '' ]
  do
    echo "Y'a un $PROCESS qui tourne, on fait $NBMES mesures en $(echo "$NBMES * $INTER"|bc)s"
    top -b -n $NBMES -d $INTER -p $PID|env LANGUAGE=C LANG=C awk -v pid=$PID '
BEGIN {
  minC=100; maxC=0; moyC=0; minM=100; maxM=0; moyM=0.0;i=0
}
$0 ~ pid {
  i++;
  if ($9 <minC) {minC=$9};
  if ($9 > maxC) {maxC=$9};
  moyC += $9;
  if ($10 <minM) {minM=$10};
  if ($10 > maxM) {maxM=$10};
  moyM += $10;
  print "CPU: " $9 "% \tRAM: " $10 "%"
}
END {
  if (i>0) {
    print "Sur " i " itérations";
    print "CPU => min: " minC "\tmax: " maxC "\tmoy " moyC/i;
    print "RAM => min: " minM "\tmax: " maxM "\tmoy " moyM/i;
  }
  else {
    print "Aucune itération sur le PID " pid;
  }
}'
    PID=$(pidof java|awk '{print $1}')
  done
  echo "Pas de process $PROCESS en cours, on attend ('Ctrl + c' pour arrêter)"
done