-1

i have table with columns. In first column, i have time, when the user has logged, in second column, i have a name of user.

13:15:39  fxs1cia1qulm1lk  
13:15:39  fxs1cia1qulm1lk  
13:15:39  fxs1cia1qulm1lk  
13:15:42  faaaa2aa11111  
13:15:49  terd1sfsd11fsdf  
13:15:49  terd1sfsd11fsdf  
13:15:49  terd1sfsd11fsdf  
13:15:59  21erdsf123sdfsdf   
13:15:59  21erdsf123sdfsdf   
13:15:59  21erdsf123sdfsdf   
13:15:59  21erdsf123sdfsdf   
13:17:50  abcasbbabadab  
13:17:50  abcasbbabadab  
13:17:50  abcasbbabadab  
13:17:50  abcasbbabadab   
13:19:19  fxs1ce1iulmla   
13:19:19  fxs1ce1iulmla  
13:19:19  fxs1ce1iulmla   
13:20:42  faaa2a0a1111

So, what i should do. I should to make uniq uperation with this two columns, Andm if the time of user logging and the name of user are same, i should say, that user has logged more than 3 times. I have written short script:

log_file=/root/log
temp_file=/root/temp
temp_file2=/root/temp2

cat /dev/null > $temp_file
cat /dev/null > $temp_file2
cat /dev/null > $result_file

cat $log_file | awk '{print $1}' | tail -n 20 > $temp_file
cat $log_file | awk '{print $5}' | tail -n 20 > $temp_file2

for i in `uniq -c $temp_file | awk '{print $1}'`; do
for y in `uniq -c $temp_file2 | awk '{print $2}'`; do
if [ $i -gt 3 ] && [ $y -gt 3 ]; then
s=`uniq -c $temp_file2 | awk '$1 == '$i`
echo "The user $s has logged more than 3 times"
fi
done
done

Please, check, how you thing, this script is correct ? Because, after output of my script in echo, i have that:

The user       4 21erdsf123sdfsdf   
      4 abcasbbabadab  has logged more than 3 times
The user       4 21erdsf123sdfsdf   
      4 abcasbbabadab  has logged more than 3 times
The user       4 21erdsf123sdfsdf   
      4 abcasbbabadab  has logged more than 3 times
The user       4 21erdsf123sdfsdf   
      4 abcasbbabadab  has logged more than 3 times

But i want to have output like, this:

The user       4 21erdsf123sdfsdf has logged more than 3 times
The user       4 abcasbbabadab  has logged more than 3 times

And that's all. Where i have a mistake ? Please help.

Valeriu
  • 57
  • 2
  • 9
  • 1
    There's a newline at the end of `$s`. See http://stackoverflow.com/questions/10618798/removing-new-line-character-from-incoming-stream-using-sed – chicks Jan 21 '17 at 13:23
  • Also `> foo` will truncate a file so the `cat /dev/null` just adds noise. – chicks Jan 21 '17 at 13:24

2 Answers2

3

You can do this in a very straightforward manner with awk

awk '{ users[$2]++ }
END {
     for (user in users)
       if (users[user] > 1)
         printf "%s logged in %d times\n", user, users[user]
    }' < /root.log

This program scans the root.log creating an associative array (aka hash) with counts of every user, then prints the ones that are greater than one.

Greg Tarsa
  • 201
  • 2
  • 5
2

So, the only problem is that it's printing the same output multiple times? Why not just pipe through uniq? Dump to another temp file and then run uniq on it?

If that's not what you're asking about, I have some observations:

  • working on line separated data in bash/sh is usually more trouble than it's worth. Unless the solution is obvious, reach for a scripting language where you don't have to fiddle with IFS all the time. (If you don't know what the IFS var is, then I really really recommend staying away from bash/sh for line separated data.)
  • since you're already using awk, I bet you could do the whole thing as an awk script.
  • Since the lines you're concerned with are identical, you can do sort logfile | uniq -c.
  • You're not sorting your file prior to uniq, so uniq won't work if the identical lines aren't next to eachother. EG if bob and joe log in at the same time and thier log entries alternate.
  • there's always grep -c
  • read up on the sort command, especially -d, -n, -k and -t

UPDATE

Are you asking for advice in shell scripting or are you looking for a practical answer to the question of how do I find out who is currently logged into 3 or more sessions?

scripting advice:

  • I'm pretty sure $s contains the whole string 4 21erdsf123sdfsdf <newline> 4 abcasbbabadab including a newline. I can't quite figure out why.
  • Why do you do awk '{print $5}'? I tried copying your example data and running it through awk '{print $5}' and I got a bunch of newlines and nothing else.
  • Have you looked at the contents of $temp_file and $temp_file2 to make sure they're what you expect?
  • The tail -n 20 tells me you just want 'recent' entries and you don't care how recent. Is this true?
  • The cat /dev/null > $file lines are redundant, just take them out.
  • Replace the cat $logfile with sort $logfile
  • Indent your loops

Basically this script won't do what you want, and I can't tell how you intended it to work, so I can't give more specific advice. Sorry.

practical

  • use @greg-tarsa's awk script ('pologies to 'e, Greg me heartie, I h'aint the knowin' o' linkn' t' a user we' a space in 'is name)
  • are you talking about current logins to a unix box? Have you tried the who command? EG who | awk '{ print $1}' | sort | uniq -c | sort -d -r or the last command?
  • search for the answer to your overall question (how do I find out who is/has logged in too many times) instead of the more specific question that's blocking the solution you're already trying to implement (Uniq by two columns with two conditions). If you're more interested in practicing your shell scripting, ask your question in a way that says that.
Dylan Martin
  • 548
  • 4
  • 14
  • Don't forget the UUOC at every opportunity too ;) – user9517 Jan 20 '17 at 19:54
  • I want to get uniq user auth. And make conditions, where if the time of auth is repeating one by one without changes, i should say, that it user has made auth more 3 times. – Valeriu Jan 20 '17 at 20:20