Команда для поиска первого и последнего имени пользователя в системе для каждой среды в bash? - PullRequest
0 голосов
/ 31 марта 2020

Мне удалось получить все журналы входа в систему за среду. Но я не могу получить первый и последний логин каждого дня, в который это среда.

Прогресс на данный момент - `last | grep '^ [^ reboot]. * Wed'

Благодаря вышесказанному я достигаю этого: -

    cent     pts/0        :0               Wed Mar 11 11:57 - 11:41 (19+23:44)
    cent     pts/0        :0               Wed Mar  4 11:10 - 11:57 (7+00:46)
    cent     :0           :0               Wed Mar  4 11:10 - 11:42 (27+00:31)
    cent     pts/0        :0               Wed Jan 22 11:27 - crash (4+10:10)
    cent     :0           :0               Wed Jan 22 11:27 - crash (4+10:10
    cent     pts/0        :0               Wed Jan 22 11:12 - 11:21  (00:09)
    cent     pts/0        :0               Wed Jan  8 11:22 - 11:54 (12+00:32)
    cent     :0           :0               Wed Jan  8 11:21 - down  (14+00:00)

Но ожидаемый результат должен быть таким: -

    cent     pts/0        :0               Wed Mar 11 11:57 - 11:41 (19+23:44)
    cent     pts/0        :0               Wed Mar  4 11:10 - 11:57 (7+00:46)
    cent     :0           :0               Wed Mar  4 11:10 - 11:42 (27+00:31) 
    cent     pts/0        :0               Wed Jan 22 11:27 - crash (4+10:10)
    //Second entry omitted as we are supposed to only display first and last
    //login each day
    cent     pts/0        :0               Wed Jan 22 11:12 - 11:21  (00:09) 
    cent     pts/0        :0               Wed Jan  8 11:22 - 11:54 (12+00:32)
    cent     :0           :0               Wed Jan  8 11:21 - down  (14+00:00)

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Попробуйте это:

#! /bin/bash

set -eu
export LC_ALL=C

# Generate a list of all abbreviations of all months.
months=($(for d in 1970-{1..12}-1; do date -d $d +%b; done))

# Convert the list of months into a regular expression suitable for sed.
months_rx=$(tr ' '  '|' <<<"${months[@]}" | sed 's/|/\\|/g')

# Read `last`s output into a variable, because we need it more than once.
last="$(last -F)"

# Build a list of date patterns for all Wednesdays, when a login happened.
dates=$(sed -n 's/.*Wed \('"$months_rx"'\) \(..\) ..:..:.. \(....\) - .*/\1 \2 ..:..:.. \3/p' <<<"$last" | uniq)

# Filter `last`s output for each date pattern and print the first and last line.
while read d; do
  sed -n "/$d - /p" <<<"$last" | sed -n '1p;$p'
done <<<"$dates"
0 голосов
/ 31 марта 2020

Вы можете сделать это с помощью простого awk сценария:

##script.awk

# at the end, display the results
END { for (i in last_login) {
        print i":"
        print "first: " first_full[i] 
        print "last: " last_full[i] 
    }
}

function add_entry(date, hour, full) {
    # test if last_login login for given date has been set
    if (last_login[date])  {
        # if so, compare with given hour, which is the latest
        if (last_login[date] < hour) {
            #if new hour is the latest, record it and login info
            last_login[date] = hour;
            last_full[date] = full
        } 
    } else {
        # no previous login recorded for this date, record the login
        last_login[date] = hour;
        last_full[date] = full
    }

    # same logic in first login
    if (first_login[date])  {
        if (first_login[date] > hour) {
            first_login[date] = hour;
            first_full[date] = full;
        } 
    } else {
        first_login[date] = hour;
        first_full[date] = full;
    }
}

# if you have `Wed` in line, parse it
/Wed/ {
    add_entry($5"/"$6, $7, $0)
}

Теперь вы можете проверить это:

last | awk -f script.awk
...