Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/10/2015, à 15:13

nqrkko

[RESOLU] Bash : Extraire et compter le nombre d'occurences

Bonjour à tous,

Je rencontre actuellement un problème sur une partie d'un script bash. Cette partie a pour but de m'informer des tentatives de connexion SSH fructueuses.
Voici mon fichier d’origine "accepted.txt" (c’est un extrait de mon fichier auth.log).

riri 192.168.1.19
titi 192.168.1.8
titi 192.168.1.8
titi 192.168.1.17
roro 192.168.1.22
roro 192.168.1.22
roro 192.168.1.38
rara 192.168.2.18

Je souhaiterais, à partir de cet extrait, obtenir le résultat suivant :

riri
192.168.1.19 : 1 fois
titi
192.168.1.8 : 1 fois
192.168.1.17 : 1 fois
roro
192.168.1.22 : 2 fois
192.168.1.38 : 1 fois
rara
192.168.2.18 : 1 fois

J'ai commencé à développer mon script mais je bloque complètement. Lorsque je l'exécute, j'obtiens le même résultat que le fichier de départ avec en prime le message d'erreur suivant (au départ) : ./test.sh: 13: ./test.sh: [riri: not found

Mon script est le suivant :

#!/bin/sh
prev_user=""
prev_ip=""
rm ssh-ok.txt
cat accepted.txt | while read ligne ; do
        set $(echo $ligne)
        user=$(eval echo $1)
        ip=$(eval echo $2)
        number=$(eval echo $3)

        if ["$user" == "$prev_user" && "$ip" == "$prev_ip"]; then
                number=$((number+1))
                awk '{print $1,$2,$number}' $line >> ssh-ok.txt
                else
                awk '{print $1,$2}' $line >> ssh-ok.txt
        fi
        prev_user=$user
        prev_ip=$ip
done < accepted.txt
cat ssh-ok.txt

Dans ce script, ne sachant pas comment compter le nombre d’occurrence et l'incrémenter à chaque fois, j'ai inséré la variable "number" et ai modifié mon fichier d'origine en ajoutant "1" à la fin de chaque ligne.

Quelqu'un aurait-il une idée des modifications à apporter pour obtenir le résultat que je souhaites s'il vous plait.

Merci par avance pour votre aide !

Dernière modification par nqrkko (Le 29/10/2015, à 19:24)

Hors ligne

#2 Le 29/10/2015, à 15:49

Postmortem

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Salut,
Alors déjà, soit on fait :

cat accepted.txt | while read ligne ; do
   blabla
done

Soit :

while read ligne ; do
   blabla
done < accepted.txt

==========================================
Plutôt que :

while read ligne ; do
        set $(echo $ligne)
        user=$(eval echo $1)
        ip=$(eval echo $2)
        number=$(eval echo $3)
       ...

Fait directement :

while read user ip; do
...
done < accepted.txt

(le « number=$(eval echo $3) » ne sert à rien dans ton script, il n'y a que 2 champs sur chaque ligne dans le fichier d'origine)
==========================================
Pour les tests, il faut des espaces en plus et « && » n'est pas accepté entre simple crochets (mais ça l'est entre les doubles); donc soit :

if [ "$user" == "$prev_user" -a "$ip" == "$prev_ip" ]

Soit :

if [[ $user == $prev_user && $ip == $prev_ip ]]

(la suppression des doubles quotes est volontaire dans la 2ème proposition, ils sont inutiles, la variable n'est pas "découpée" entre double-crochets)
==========================================
Et pour info, on ne fait pas ce genre de chose :

ip=$(eval echo $2)

Mais simplement :

ip=$2

Edit :
Le titre de la discussion est « Bash : ... » ; pourquoi commences tu donc ton script par « #!/bin/sh » ??? Si tu veux du bash, il faut mettre « #!/bin/bash ».

Re-edit : sinon, un petit (g)awk :

awk '{ nb[$1][$2]++ } END{ for (i in nb) { printf "%s\n", i; for (j in nb[i]) printf "%s : %s fois\n", j, nb[i][j] }}' accepted.txt

Dernière modification par Postmortem (Le 29/10/2015, à 16:33)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#3 Le 29/10/2015, à 18:20

Compte anonymisé

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Bonjour,

je propose cette solution (qui tri par ordre alphabétique en plus) :

for b in $(cat accepted.txt | awk '{print $1}'|uniq|sort)
do echo $b
cat accepted.txt|grep $b|awk '{print $2}'|uniq -c|sort
done
résultat a écrit :

$ sh test.sh
rara
      1 192.168.2.18
riri
      1 192.168.1.19
roro
      1 192.168.1.38
      2 192.168.1.22
titi
      1 192.168.1.17
      2 192.168.1.8

le nombre d'occurence est affiché avant l'adresse IP

Dernière modification par Compte anonymisé (Le 29/10/2015, à 18:23)

#4 Le 29/10/2015, à 19:23

nqrkko

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Bonsoir à vous,

Merci pour tes remarques Postmortem, elles vont me permettre de m'améliorer (et j'ai du travail) dans le scripting en "bash" wink

Anonyme68, merci beaucoup pour ce très léger script, il est concis et répond tout à fait à mes attentes !

Bonne soirée à vous !

Hors ligne

#5 Le 29/10/2015, à 20:16

Postmortem

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Anonyme68 a écrit :

Bonjour,

je propose cette solution (qui tri par ordre alphabétique en plus) :

for b in $(cat accepted.txt | awk '{print $1}'|uniq|sort)
do echo $b
cat accepted.txt|grep $b|awk '{print $2}'|uniq -c|sort
done
résultat a écrit :

$ sh test.sh
rara
      1 192.168.2.18
riri
      1 192.168.1.19
roro
      1 192.168.1.38
      2 192.168.1.22
titi
      1 192.168.1.17
      2 192.168.1.8

le nombre d'occurence est affiché avant l'adresse IP

« cat | grep | awk | .... » c'est quand même laid !! tongue


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#6 Le 29/10/2015, à 21:59

Compte anonymisé

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Oui j'ai fait en 5 minutes smile

Il y a surement moyen de faire plus propre

#7 Le 29/10/2015, à 22:18

Compte anonymisé

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

voilà un peu plus propre :

for b in $(awk '{print $1}' accepted.txt|uniq|sort)
do echo $b
grep $b accepted.txt|awk '{print $2}'|uniq -c|sort
done

#8 Le 30/10/2015, à 06:48

pingouinux

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Bonjour,
@Anonyme68 #7 : uniq ne voit les lignes identiques que si elles sont consécutives. Je pense que le sort doit être avant.

Ajouté :
La même chose en python, mais c'est moins concis

#!/usr/bin/env python

with open('./accepted.txt','r') as f: ligs=f.readlines()

tab={}
for lig in ligs:
   user,ip=lig.split()
   if not user in tab: tab[user]={}
   if not ip in tab[user]: tab[user][ip]=0
   tab[user][ip]+=1

for user in sorted(tab):
   print(user)
   for ip in tab[user]: print("\t%-15s : %2s fois"%(ip,tab[user][ip]))

Édité : Un peu plus condensé

#!/usr/bin/env python

with open('./accepted.txt','r') as f: 

   tab={}
   for lig in f:
      user,ip=lig.split()
      tab.setdefault(user,{})
      tab[user].setdefault(ip,0)
      tab[user][ip]+=1

   for user in sorted(tab):
      print(user)
      for ip in tab[user]: print("\t%-15s : %2s fois"%(ip,tab[user][ip]))

Dernière modification par pingouinux (Le 30/10/2015, à 08:13)

Hors ligne

#9 Le 30/10/2015, à 10:26

Compte anonymisé

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Bien vu pingouinux !

Du coup :

for b in $(awk '{print $1}' accepted.txt|sort|uniq)
do echo $b
grep $b accepted.txt|awk '{print $2}'|sort|uniq -c
done

#10 Le 30/10/2015, à 13:47

Postmortem

Re : [RESOLU] Bash : Extraire et compter le nombre d'occurences

Version triée avec gawk :

awk '{ nb[$1][$2]++ }
   END { nb_users=asorti(nb, users)
        for (i=1; i<=nb_users; i++) {
           printf "%s\n", users[i]
           nb_ips=asorti(nb[users[i]], ips)
           for (j=1; j<=nb_ips; j++) printf "%s : %s fois\n", ips[j], nb[users[i]][ips[j]]
        }
   }' accepted.txt

Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne