Управление многими туннельными соединениями ssh

Похоже, если мы используем необязательный двоеточие :, за которым следуют как минимум два пробела в качестве FS (FS = ":? *"), большинство основных полей, используемых в этой задаче, можно изолировать без проблем с дополнительными пробелами:

$ cat t20.awk
BEGIN { FS=":?   *"; OFS = ", "; SEP = "; "; }

# if $2 is "Type", append $3 to T
$2 == "Type" { T = (T ? T SEP : "") $3;}

# if $2 is "Retention Level", append sub-string in parenthesis to L
$2 == "Retention Level" && match($0, /\(.*?\)/) {
    L = (L ? L SEP : "") substr($0, RSTART+1, RLENGTH-2)
}

# in Daily window block, skip all line without " --> "
# use an associative array "a" to make sure unique time range
/Daily Windows:/,/^\s*$/ {
    if (!/ --> /) next
    key = $3 " --> " $6
    if (!a[key]++) S = (S ? S SEP : "") key
}

END { print T, L, S }

Примечание:

  1. в S = (S ? S SEP : "") key, тернарный (S ? S SEP : "")должен избегать начального SEP при объединении строк, аналогично тому, как это происходит при объединении T, L.

  2. в substr($0, RSTART+1, RLENGTH-2), используя RSTART+1для удаления начального (и RLENGTH-2для удаления двух скобок

Запустите код:

$ awk -f t20.awk file.txt
#Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks, 00:00:00 --> 07:00:00; 00:00:00 --> 10:00:00; 01:00:00 --> 16:00:00

Обновление:

Основываясь на вашем описании в комментариях, я внес следующие коррективы в код части Daily Windows:

  • Добавлен флаг dw _на для обозначения начала и конца блока Daily Windows . Все строки с dw_on == 1и соответствующие шаблону / --> /должны быть проверены на S. этот флаг будет сброшен на 0при обнаружении следующей ПУСТОЙ строки /^\s*$/
  • Добавлена ​​переменная cnt _DW для подсчета количества ежедневных записей Windows в каждом расписании. это будет сбрасываться в начале каждого блока Daily Windows

Уникальность поддерживается хэшем (ассоциативным массивом)и , который будет сбрасываться в начале каждого блока Daily Windows. Ключ этого хеша — key = $3 " --> " $6, это окно, которое вы хотите получить. синтаксис:if (!a[key]++) S = (S ? S SEP : "") keyтакой же, как

  if (!a[key]) { 
      a[key] = a[key] + 1
      S = (S ? S SEP : "") key 
  }

поэтому, только если ключ не виден до (a[key]="" ), можно keyдобавить к S, второй раз, когда тот же ключ обрабатывается, он уже иметь a[key]==1и пропустить указанный выше блок кода. Это один из распространенных в awkспособов проверки уникальности.

$ cat t20.1.awk
BEGIN { FS=":?   *"; OFS = ", "; SEP = "; "; }

# if $2 is "Type", append $3 to T
$2 == "Type" { T = (T ? T SEP : "") $3;}

# if $2 is "Retention Level", append sub-string in parenthesis to L
$2 == "Retention Level" && match($0, /\(.*?\)/) {
    L = (L ? L SEP : "") substr($0, RSTART+1, RLENGTH-2)
}

/Daily Windows:/ {
    # turn on the dw_on flag and reset cnt_DW (number of DW entries in a section)
    dw_on = 1; cnt_DW=0;
    # reset the hash 'a' for uniqueness check
    # if you need the uniqueness across all Schedules, then comment it out
    delete a; 
    next;
}

# if dw_on flag is true, i.e. "dw_on == 1"
dw_on {
    # match " --> ", then increase cnt_DW, check the unique window
    # and then append qualified entry to "S"
    if (/ --> /) {
        cnt_DW++
        key = $3 " --> " $6
        if (!a[key]++) S = (S ? S SEP : "") key
    # else if EMPTY line, reset dw_on flag, if cnt_DW is 0, append "No Window" to S
    } else if (/^\s*$/) {
        dw_on = 0;
        if (!cnt_DW) S = (S ? S SEP : "") "No Window"
    }
}

END { 
    # last Schedule section does not have a EMPTY line, so we will need
    # to check up cnt_DW in the last Schedule section in "END" block
    if(dw_on && !cnt_DW) S = (S ? S SEP : "") "No Window";

    # print the result.
    print T, L, S 
}

Я внес следующие небольшие изменения в ваши исходные данные, чтобы протестировать приведенный выше код:

  1. удалена единственная запись Daily Windowsво 2-м разделе Schedule
  2. заменил строку Friday 00:00:00 --> Friday 07:00:00в первом Приложении на Friday 01:00:00 --> Friday 16:00:00, что совпадает с разделом 3-го Приложения.

Итак, теперь в 1-м Расписании есть 2 уникальных окна, во 2-м Расписании нет окна, в 3-м Расписании есть 1 уникальное окно, такое же, как и в 1-м Расписании.

Запустите обновленный код с указанными выше данными, вы получите:

awk -f t20.1.awk file.txt 
#Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks, 00:00:00 --> 07:00:00; 01:00:00 --> 16:00:00; No Window; 01:00:00 --> 16:00:00

Обратите внимание, что их два 01:00:00 --> 16:00:00, потому что они находятся в разных расписаниях. Если вы хотите удалить последний 01:00:00 --> 16:00:00, закомментируйте строку delete a, как показано в коде, вы получите следующий результат:

#Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks, 00:00:00 --> 07:00:00; 01:00:00 --> 16:00:00; No Window
0
03.02.2020, 10:31
1 ответ

Простым методом может быть создание сценария Bash, который запускает их все. В приведенном ниже примере сценария, написанном для двух соединений, если вы назовете его tunnelи chmod +x tunnel, вы можете использовать

tunnel start

чтобы запустить их (идемпотентно )и

tunnel stop

, чтобы очистить их.

#!/bin/bash
C1="localhost:8866:127.0.0.1:3478 host1"
C2="localhost:8867:127.0.0.1:3478 host2"
pkill -f "$C1"
pkill -f "$C2"
if [ "$1" = stop ]; then exit 0; fi
sleep 3  # give some time for them to exit, if applicable
nohup ssh -N -L $C1 &> /dev/null &
nohup ssh -N -L $C2 &> /dev/null &

Другим методом может быть использование autossh, чтобы поддерживать их работу по отдельности и, возможно, организовать их запуск при запуске системы.

Наконец, вы можете давать символические имена портам в /etc/services, хотя тогда мы начинаем создавать некоторую путаницу в конфигурации вашей системы. Вы можете предпочесть, чтобы порты находились в зарезервированном диапазоне (< 1024 ), что требует привилегий root.

0
28.04.2021, 23:24

Теги

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