Home > Software engineering >  Show with star symbols how many times a user have logged in
Show with star symbols how many times a user have logged in

Time:12-16

I'm trying to create a simple shell script showing how many times a user has logged in to their linux machine for at least one week. The output of the shell script should be like this:

2021-12-16
****
2021-12-15
**
2021-12-14
*******

I have tried this so far but it shows only numeric but i want showing * symbols.

user="$1"
last -F | grep "${user}" | sed -E "s/${user}.*(Mon|Tue|Wed|Thu|Fri|Sat|Sun) //" | awk   '{print $1"-"$2"-"$4}' | uniq -c

Any help?

CodePudding user response:

You might want to refactor all of this into a simple Awk script, where repeating a string n times is also easy.

user="$1"
last -F |
awk -v user="$1" 'BEGIN { split("Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec", m, ":");
    for(i=1; i<=12; i  ) mon[m[i]] = sprintf("i, i) }
$1 == user {   count[$8 "-" mon[$5] "-" sprintf("i", $6)] }
    END { for (date in count) {
        padded = sprintf("%-" count[date] "s", "*");
        gsub(/ /, "*", padded);
        print date, padded } }'

The BEGIN block creates an associative array mon which maps English month abbreviations to month numbers.

sprintf("i", number) produces the value of number with zero padding to two digits (i.e. adds a leading zero if number is a single digit).

The $1 == user condition matches the lines where the first field is equal to the user name we passed in. (Your original attempt had two related bugs here; it would look for the user name anywhere in the line, so if the user name happened to match on another field, it would erroneously match on that; and the regex you used would match a substring of a longer field).

When that matches, we just update the value in the associative array count whose key is the current date.

Finally, in the END block, we simply loop over the values in count and print them out. Again, we use sprintf to produce a field with a suitable length. We play a little trick here by space-padding to the specified width, because sprintf does that out of the box, and then replace the spaces with more asterisks.

CodePudding user response:

A simple soluction, using tempfile

#!/bin/bash
user="$1"
tempfile="/tmp/last.txt"
IFS='
'

last -F | grep "${user}"  | sed -E "s/"${user}".*(Mon|Tue|Wed|Thu|Fri|Sat|Sun) //" | awk   '{print $1"-"$2"-"$4}' | uniq -c > $tempfile

for LINE in $(cat $tempfile)
    do
        qtde=$(echo $LINE | awk '{print $1'})
        data=$(echo $LINE | awk '{print $2'})
        echo -e "$data "

        for ((i=1; i<=qtde; i  ))
        do
                 echo -e "*\c"
        done
        echo -e "\n"
done
  • Related