Szukanie najaktywniejszego linux

0

Napisz skrypt, który znajdzie najaktywniejszego w tym miesiącu użytkownika
serwera student, wypisze ile raz się logował i poda czas ostatniego logowania.

na pewno wiem ze trzeba uzyć last, nastepnie jakoś zliczyć powtarzające sie linie i wybrać tą ktora powtarza się najcześciej
myślałem że last | uniq -c wystarczy, ale nie daje rady

0

No nie wystarczy, bo uniq działa tylko na liniach następujących po sobie i cała linia musi się powtarzać, co oczywiście nie ma miejsca w last. Masz więc 2 podejcia:

  1. Listujesz, wycinasz tylko 1 słowo, sortujesz, liczysz wystąpienia, sortujesz po ilości wystąpień, wypisujesz "szczyt" (parę poleceń pipowanych)
  2. Listujesz, liczysz ile razy występuje 1 słowo w każdej linii i drukujesz (samo AWK wystarczy)
0

Wybrałbym sposób nr 1, bo sam bym tak pomyślał.
czyli pewnie last | cut -d ' ' -f 1 | sort | uniq -c | sort -r | head -1 ??

0

Musisz sortować numerycznie. Domyślnie sort sortuje leksykograficznie.

0

jedynie co mi przychodzi do głowy to sort -rn
ale wpisywalem to juz i nie przynioslo rezultatu

0

Może tak?

last | awk '{print $1;}' | sort | uniq -c
0

wynik pokazuje mi dobry, tylko brakuje mi jednej dodatkowej kolumny, którą wycinam na początku.
przykładowo output mam: 38 logowań nazwa_użytkownika
a powinienem: 38 logowań nazwa_użytkownika 30/12/2020 14:31

0

No to na szybko umiem tak:

last | awk '{print $1;}' | sort | uniq -c | {
    read # skip first line

    while read foo
    do
        name=$(echo $foo | awk '{print $2;}')
        count=$(echo $foo | awk '{print $1;}')
        date=$(last | grep -P "^$name" \
                    | head -n 1 \
                    | sed 's/^.*\(Mon\|Tue\|Wed\|Thu\|Fri\|Sat\|Sun\)/\1/'\
                    | sed 's/-.*$//')

        printf '%d\t%s\t%s\n' $count $name "$date"
    done
}

To chyba nie do końca to co chcesz, ale sobie pokombinujesz z datą i powinno styknąć.

4

@elwis: jak już używamy AWK, to po co tak komplikować?

last | awk -F'  +' '{ count[$1] += 1; if (!last[$1]) last[$1] = $3 } END { for (key in count) if (count[key] > max) { name = key; max = count[name] }; print name, count[name], last[name] }'

Masz wszystko w jednym wywołaniu AWK i jest całkiem czytelnem, a na pewno bardziej niż to co Ty przedstawiłeś. No i robi wszystko w jednym przebiegu, a nie odpala last parę razy pod rząd.

0

Już nie rozumiem. to temat na całą konsultację. Polecam ci rozwiązanie @hauleth. — elwis 4 minuty temu

#!/bin/sh
ZMIENNA= last | cut -d ' ' -f 1 | sort | uniq -c | sort -r | head -1
echo $ZMIENNA
#wyswietli mi ilosc logowan + nazwe usera
# i teraz dałbym echo i wyswietlenie ostatniego logowania tego usera ze $ZMIENNA przy pomocy cut
0

@cryptondr: Po pierwsze, w linii 2, musiałbyś wziąć to wywołanie w $() bo inaczej w zminnej zapisze ci kod powrotu, a nie treść.

I dalej problem polega na tym, że ten cały pipeline zwróci ci wiele linii i dla każdej z nich jeszcze trzeba jeszcze jedno wywołanie zrobić, żeby uzyskać datę ostatniego wywołania. W tym celu właśnie zaproponowałem tę pętlę for, którą iterujemy po tych kolejnych liniach i pobieram tę datę.

0
cryptondr napisał(a):

Napisz skrypt, który znajdzie najaktywniejszego w tym miesiącu użytkownika

# wyznacza poczatek miesiaca
MONTH_START=$(date +%Y-%m-01)

# przegalda baze logowan od poczatku biezacego miesiaca 
last -s $MONTH_START 

A dalej najprościej awkiem, tak jak proponuje @hauleth

1 użytkowników online, w tym zalogowanych: 0, gości: 1