135 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
 | 
						|
urequire DEFAULTS
 | 
						|
 | 
						|
function display_help() {
 | 
						|
    uecho "$scriptname: Afficher le résultat d'une recherche par regexp et compter
 | 
						|
éventuellement leurs occurences
 | 
						|
 | 
						|
USAGE
 | 
						|
    $scriptname [options] [regexp]
 | 
						|
 | 
						|
Chaque ligne *entière* de stdin est mise en correspondance avec l'expression
 | 
						|
regulière qui doit avoir la syntaxe de awk. S'il y a correspondance, afficher
 | 
						|
soit toute l'expression matchée, soit chaque groupe s'il y a des expressions
 | 
						|
parenthésées, chacun des groupes étant séparé par le caractère sep.
 | 
						|
 | 
						|
Si l'expression régulière n'est pas spécifiée, elle vaut par défaut '.*' ce qui
 | 
						|
fait que toutes les lignes correspondent. Ceci peut être utile avec les options
 | 
						|
-s et -c.
 | 
						|
 | 
						|
Certaines expressions régulières sont prédéfinies. regexp peut avoir l'une des
 | 
						|
valeurs prédéfinies suivantes:
 | 
						|
 | 
						|
    ip --> "'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'"
 | 
						|
 | 
						|
OPTIONS
 | 
						|
    -F sep
 | 
						|
        Spécifier le caractère séparateur en sortie s'il faut afficher des
 | 
						|
        champs multiples. Par défaut, utiliser le caractère ':'
 | 
						|
        Si un séparateur vide est spécifié, le séparateur standard de awk est
 | 
						|
        utilisé.
 | 
						|
    -s  Trier le résultat
 | 
						|
    -C FIELDNUM
 | 
						|
    -c, --count
 | 
						|
        Compter les occurences successives de la valeur du champ FIELDNUM, et
 | 
						|
        afficher une ligne de la forme 'count<sep>last_line' pour chaque groupe,
 | 
						|
        last_line étant la dernière occurence du groupe. L'option -c correspond
 | 
						|
        à '-C 0', c'est à dire compter les occurences successives de toute les
 | 
						|
        lignes.
 | 
						|
        Le séparateur utilisé pour calculer le numéro de champ est sep, spécifié
 | 
						|
        avec l'option -F.
 | 
						|
    -a, --all-lines
 | 
						|
        Avec les options -c/-C, afficher toutes les lignes des occurences
 | 
						|
        successives au lieu de seulement la ligne de la dernière occurence. Ceci
 | 
						|
        est utile surtout avec l'option -C, pour voir les différences avec les
 | 
						|
        différentes lignes.
 | 
						|
    -m, --multiple
 | 
						|
        Avec les options -c/-C, n'afficher que les lignes dont le compte est
 | 
						|
        supérieur à 1. Avec l'option -a, les groupes contigus sont séparés par
 | 
						|
        une ligne '--'"
 | 
						|
}
 | 
						|
 | 
						|
function match() {
 | 
						|
    local regexp="$1" sep="$2"
 | 
						|
    awkrun ${sep:+FS="$sep"} '{
 | 
						|
      pos = match($0, /'"${regexp//\//\\/}"'/, out)
 | 
						|
      if (pos != 0) {
 | 
						|
        max = length(out) / 3
 | 
						|
        if (max == 1) {
 | 
						|
          print out[0]
 | 
						|
        } else {
 | 
						|
          line = ""
 | 
						|
          for (i = 1; i < max; i++) {
 | 
						|
            if (i > 1) line = line FS
 | 
						|
            line = line out[i]
 | 
						|
          }
 | 
						|
          print line
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }'
 | 
						|
}
 | 
						|
function count() {
 | 
						|
    local field="$1" sep="$2" all_lines="$3"
 | 
						|
    awkrun field="$field" ${sep:+FS="$sep"} all_lines="$all_lines" '
 | 
						|
      BEGIN {
 | 
						|
        first = 1
 | 
						|
        lastfield = ""
 | 
						|
        lastline = ""
 | 
						|
        count = 0
 | 
						|
        if (all_lines == "") all_lines = 0
 | 
						|
        else all_lines = 1
 | 
						|
      }
 | 
						|
      !first && $field != lastfield {
 | 
						|
        if (!all_lines) print count FS lastline
 | 
						|
        count = 0
 | 
						|
      }
 | 
						|
      {
 | 
						|
        count = count + 1
 | 
						|
        lastfield = $field
 | 
						|
        lastline = $0
 | 
						|
        first = 0
 | 
						|
        if (all_lines) print count FS lastline
 | 
						|
      }
 | 
						|
      END {
 | 
						|
        print count FS lastline
 | 
						|
      }
 | 
						|
    '
 | 
						|
}
 | 
						|
 | 
						|
sep=:
 | 
						|
sort=
 | 
						|
count=
 | 
						|
all_lines=
 | 
						|
multiple=
 | 
						|
parse_opts "${PRETTYOPTS[@]}" \
 | 
						|
    --help '$exit_with display_help' \
 | 
						|
    -F: sep= \
 | 
						|
    -s sort=1 \
 | 
						|
    -c,--count count=0 \
 | 
						|
    -C: count= \
 | 
						|
    -a,--all-lines all_lines=1 \
 | 
						|
    -m,--multiple multiple=1 \
 | 
						|
    @ args -- "$@" && set -- "${args[@]}" || die "$args"
 | 
						|
 | 
						|
regexp="$1"
 | 
						|
[ -n "$regexp" ] || regexp=".*"
 | 
						|
 | 
						|
case "$regexp" in
 | 
						|
ip) regexp='[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+';;
 | 
						|
esac
 | 
						|
 | 
						|
cmd="$(qvals match "$regexp" "$sep")"
 | 
						|
[ -n "$sort" ] && cmd="$cmd | sort"
 | 
						|
[ -n "$count" ] && cmd="$cmd | $(qvals count "$count" "$sep" "$all_lines")"
 | 
						|
if [ -n "$multiple" ]; then
 | 
						|
    if [ -n "$all_lines" ]; then
 | 
						|
        cmd="$cmd | $(qvals grep -v -B 1 "^1$sep")"
 | 
						|
    else
 | 
						|
        cmd="$cmd | $(qvals grep -v "^1$sep")"
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
eval "$cmd"
 |