powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / Unix-системы [игнор отключен] [закрыт для гостей] / Довольно непростой shell script (доработать)
4 сообщений из 4, страница 1 из 1
Довольно непростой shell script (доработать)
    #38990907
andrey10
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет! Очень добрый человек когда-то написал мне классный скрипт http://www.sql.ru/forum/1135952/shell-script-opredelit-promezhutok-vremeni , но сейчас у меня возникла необходимость переделать его под новый формат логов. К сожалению, спектр моих знаний в шелл скриптинге очень ограничен, и самостоятельно доработать его у меня ну никак не получается.

Новый формат выглядит так:
2015-06-20 22:10:08 USERID: 10005 N1 N4 Login UNM:[Earth] N3
2015-06-20 23:10:11 USERID: 10006 N2 N5 Login UNM:[Moon] N4
2015-06-20 23:20:55 USERID: 10005 FD G5 Logout U1
2015-06-21 02:35:42 USERID: 10006 N2 N5 Logout Y0
(жирным я выделил колонки, которые присутствуют в логе, но их обрабатывать не нужно)

Вывод нужен такой:
10005 2015-06-20 Earth 22:10 01:10
10006 2015-06-20 Moon 23:10 03:25



Обратите внимание, что USERID 10006 залогинился, условно, сегодня, а вышел уже завтра. Нужно правильно посчитать время от логина до логаута (когда я пытался переделать скрипт, использовал это:
Код: sql
1.
date -u -d "0 $(date -d "2015-06-21 02:35:42" +%s) seconds - $(date -d "2015-06-20 23:10:11" +%s) seconds" +"%H:%M"

). Не знаю, может быть вам это подскажет что-нибудь.

Формат 4 колонки для меня не важен. Можете вывести так: 3:25, или так: 3h25m. Как вам будет удобно. И секунды выводить нет необходимости.

Иногда случается так, что для конкретного USERID, после "Login" не всегда идет "Logout". Бывает несколько "Login" подряд:
2015-06-20 22:10:08 USERID: 10005 N1 N4 Login UNM:[Earth] N3
2015-06-20 22:15:08 USERID: 10005 N1 N4 Login UNM:[Earth] N3
2015-06-20 23:20:55 USERID: 10005 FD G5 Logout U1

В таком случае для вычисления нужно использовать первый по счету логин. То есть вывод должен быть:
10005 2015-06-20 Earth 22:10 01:10


Надеюсь, кто-то мне поможет. Буду очень благодарен!
...
Рейтинг: 0 / 0
Довольно непростой shell script (доработать)
    #38990914
andrey10
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ой, перепутал местами время и нейм для вывода. Так как не уверен, что мне будет легко самому поменять их местами, лучше уточню. Вот такой нужен вывод:
10005 2015-06-20 22:10 Earth 01:10
10006 2015-06-20 23:10 Moon 03:25
...
Рейтинг: 0 / 0
Довольно непростой shell script (доработать)
    #38991161
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey10,
ограничения:
- файл лога заканчивается символом новой строки '\n';
- идентификаторы пользователей не содержат пробельных символов '\s';
- игнорируемые поля не содержат пробельных символов;
- последнее игнорируемое поле в записи о логине не содержит правую квадратную скобку ']'.

Код: powershell
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
#!/bin/bash

# #########################################
# параметры: нет
# имя файла для обработки - в константе INFILE
# 'основной' вывод в формате `{ИД} {дата-время логина} {имя} {длительность}`
# +
# сообщения об ошибках в формате `ERR: line# {номер строки}, {сообщение}`
# при наличии не разлогинившихся пользователей:
# `\nINFO: still logged in`
# вывод в формате `{ИД} {дата-время логина} {имя}
#

isdt () { #?дата_время
  [[ "$@" == 20[12][0-9]-@(0[1-9]|1[0-2])-@(0[1-9]|[12][0-9]|3[01])\ @([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ]] || return 1
}

datediff () { #разность дат в часах и минутах с точностью до целых минут; параметры: дата2, дата1 
  local -i _H _M
  (( _M = (`date -d "$1" +'%s'` - `date -d "$2" +'%s'`) /60,  _H = _M /60, _M -= _H *60 ))
  
  printf '%02i:%02i' ${_H} ${_M}
}

printout () { #вывод результата
  echo $@
}

showerr () { #вывод сообщения об ошибке
  local _MSG='ERR: line# %s, '$2'\n'
  printf "$_MSG" $1 "${@:3}"
}


# 
# main
#

declare -r INFILE='usrlog.txt'                                                    # файл лога
declare LOGDATE LOGTIME IGNORED_1 USERID IGNORED_2 IGNORED_3 OPERATION USERNAME   # поля записи лога
declare -i LN=0                                                                   # счетчик прочинанных строк
declare DT
declare -A LOGGEDIN UNAMES


# parse log
while read LOGDATE LOGTIME IGNORED_1 USERID IGNORED_2 IGNORED_3 OPERATION USERNAME; do
  (( LN++ ))

  if [[ -z $LOGDATE || -z $LOGTIME || -z $USERID || -z $USERNAME ]]; then
    continue    
    
  elif ! `isdt $LOGDATE $LOGTIME`; then
    # err: invalid date_time
    showerr $LN 'invalid date-time (%s %s)' $LOGDATE $LOGTIME
    
  else
    DT=$LOGDATE' '$LOGTIME
    case $OPERATION in
      Login)
        if [[ -z ${LOGGEDIN[$USERID]} ]]; then
          LOGGEDIN[$USERID]=$DT
          if [[ -z ${UNAMES[$USERID]} ]]; then
            USERNAME=${USERNAME:5}
            USERNAME=${USERNAME%]*}
            UNAMES[$USERID]=$USERNAME
          fi
        fi
        ;;
      Logout)
        if [[ -n ${LOGGEDIN[$USERID]} ]]; then
          # output result
          printout $USERID "${LOGGEDIN[$USERID]}" "${UNAMES[$USERID]}" `datediff "$DT" "${LOGGEDIN[$USERID]}"`
          unset -v LOGGEDIN[$USERID]
          
        else
          # err: logout without login
          showerr $LN 'logout w/o login (%s %s %s)' $LOGDATE $LOGTIME $USERID
        fi
        ;;
      *)        
        # err: invalid operation
        showerr $LN 'invalid operation (%s)' $OPERATION
    esac
  fi
done < "$INFILE"

if [[ ${#LOGGEDIN[@]} -gt 0 ]]; then
  echo $'\n''INFO: still logged in'
  # not logged out
  for USERID in ${!LOGGEDIN[@]}; do
    printout $USERID "${LOGGEDIN[$USERID]}" "${UNAMES[$USERID]}" # '??:??'
  done
fi

...
Рейтинг: 0 / 0
Довольно непростой shell script (доработать)
    #38992653
andrey10
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Супер, класс! Огромное-преогромное и даже еще большее спасибо!
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Unix-системы [игнор отключен] [закрыт для гостей] / Довольно непростой shell script (доработать)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]