Сценарий оболочки для подсчета только последовательных дней

Если я понимаю, на что вы надеетесь, вы сможете сделать это с помощью screen .

Общая картина экрана заключается в том, что он создает виртуальный терминал, который вы можете присоединять и отсоединять от других терминалов. Предполагая, что у вас установлен screen (я полагаю, имя пакета - это просто screen в CentOS) вот один из способов его использования:

  1. Удаленный доступ к вашей машине с помощью Putty или другого SSH-клиента.
  2. Запустить экран . Это создает виртуальный терминал, который должен выглядеть примерно так же, как то, на что вы уже смотрели.
  3. Начните свою задачу.
  4. При желании вы можете использовать Ctrl + Z в фоновом режиме, но в этом нет необходимости. Приложения будут работать даже после отключения.
  5. Отключите текущий терминал, используя Ctrl + a d . Может показаться, что вы только что что-то убили, но вы этого не сделали.
  6. Чтобы посмотреть, как это работает, запустите screen -r . Это повторно подключит ваш сеанс и вернет вас туда, где вы были до отключения. Теперь снова используйте Ctrl + d , чтобы отсоединить.
  7. Это хорошо, но то, что вас интересует, - это подключение из отдельного терминального сеанса. Это работает точно так же.Отключитесь от SSH-соединения и запустите screen -r с локального терминала. Это должно повторно подключить ваш сеанс экрана, а ваша задача по-прежнему должна выполняться.

Обратите внимание, что это поможет вам только в том случае, если вы для начала запускаете приложение на экране. Я не описал, как это сделать с процессом, который уже запущен за пределами экрана.

Вы можете сделать то же самое, используя tmux , но я описал, как это сделать с экраном, просто потому, что он старше и более распространен.

1
25.08.2016, 22:46
2 ответа

В AWK:

{
    sub(",", "", $0);  # kill first comma, thanks Thomas
    cmd="date -d \""$1" "$2" "$3" "$4" "$5" 1 day ago\" \"+%b %e\"";
    cmd|getline dt;
    close(cmd);
    if (dt==prev && blah==substr($0, index($0, $6))) { times = times + 1 }
    else { print times" "line; times = 1 };
    prev=$2" "$3;
    blah=substr($0, index($0,$6));
    line=$0;
}
END { print times" "line }

Предполагая, что у нас есть этот ввод внутри файла с именем blah.log :

Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH

И сценария awk в sequence.awk , мы можем сделать:

$ awk -f consecutive.awk blah.log

3 Tue Aug 23 2016 04:22:11 BLAH
1 Thu Aug 25 2016 05:00:00 BLAH

Что дает количество последовательных дней в качестве дополнительного столбца и печатает последнюю дату. Чтобы избавиться от даты в выводе, вы можете просто изменить время печати в строке на время печати "" blah (в двух местах, которые появляются).

Как это работает:

  • Выполняет команду даты, чтобы получить вчера из текущей строки, спасибо, glenn jackman
  • Сравнивает с сохраненной датой из предыдущей строки
  • Увеличивает счетчик или печатает
  • Сохраняет данные из текущей строки для следующего прогона

Примечания:

  • Это некрасиво (весь код AWK, преодолейте его)
  • Хорошо работает с любыми пробелами (до целого года), потому что использует дату , но игнорирует часовые пояса
  • Он считает, что BLAH может отличаться на разных линиях, и сопоставляет только появления BLAH с другими вхождениями BLAH. Если файл неупорядочен, вам может потребоваться выполнить sort -t, -k 2 .
  • Если вам нужно учитывать разные значения BLAH, вам понадобится GNU awk (благодаря вызову substr ). В противном случае вы можете прервать вызов substr , и сценарий будет работать на любом posix awk.
1
27.01.2020, 23:47

Это заняло больше времени, чем я ожидал, но сценарий ниже выполнит свою работу.

#!/bin/bash
str=" Sun Aug 21 2016 03:00:00, BLAH Mon Aug 22 2016 03:54:00, BLAH"
str+=" Tue Aug 23 2016 04:22:11, BLAH Thu Aug 25 2016 05:00:00, BLAH"
IFS='H' read -r -a inputArray <<< "$str"
days=(SunMon MonTue TueWed WedThu ThuFri FriSat SatSun)
count=1
found=0
lastOne=""
finalCount=0
for entry in "${inputArray[@]}"; do
   thisOne="${entry:1:3}"
   test="$lastOne$thisOne"
   for pair in "${days[@]}"; do
      if [ "$test" == "$pair" ]; then
         ((++count, ++found))
      fi
   done
   if [ ! $found ]; then count=1; else found=0; fi
   if [ $count -gt $finalCount ]; then
      finalCount=$count
   fi
   lastOne=$thisOne
done
echo "There were $finalCount BLAHs in a row."
0
27.01.2020, 23:47

Теги

Похожие вопросы