Вам доступен ряд опций
cron
для включения и выключения сервера ssh
iptables
, чтобы заблокировать и разблокировать порт ssh
ssh
на другом порту ssh
и назначить использование VPN . Я уверен, что доступны и другие решения, но я остановился на пяти.
Прямой -прямой awk
сценарий:
awk '
/^client/ { ipaddr = $2 }
/^[[:blank:]]*shortname/{ shortname = $3 }
/^[[:blank:]]*secret/ { secret = $0; sub("^[^=]*= ", "", secret) }
/^}/ {
printf("client %s { secret = %s, ipaddr = %s }\n",
shortname, secret, ipaddr);
}' file
Просто проанализируйте необходимые биты информации, когда мы найдем их во входном файле, и когда мы нажмем }
в начале строки, мы выведем собранную информацию в правильном формате.
Анализ текста secret
особенный, поскольку мы ожидаем, что он будет содержать что угодно , даже разделители полей. Он просто начинается с установки переменной secret
на всю строку, а затем удаляет все до первой =
и один пробел после нее.
Учитывая файл
client 192.168.100.2 {
secret = ThisIStheSECRET2
shortname = HOSTNAME2
}
client 10.0.0.1 {
secret = This is it, the secret!, ipaddr = 10.0.0.1
shortname = myhost.local
}
(обратите внимание на четыре пробела в начале секрета ), это дает
client HOSTNAME2 { secret = ThisIStheSECRET2, ipaddr = 192.168.100.2 }
client myhost.local { secret = This is it, the secret!, ipaddr = 10.0.0.1, ipaddr = 10.0.0.1 }
Это должно решить вашу проблему, хотя и не так "просто", как я надеялся:
perl -pe 's/(\w)\s*$/\1,\n/;' your_filename | perl -pe 'BEGIN{undef $/;} s/(?<!})\s*\n\s*/ /smg;' -e 's/(client )(\S+)(.*?)(\w+),\s*}/\1\4\3\2 }/g;'
Он выполняет одно регулярное выражение для добавления запятых к вашим строкам, заканчивающимся буквенно-цифровыми символами (от A до Z, от a до z, от 0 до 9 и_)
Он запускает другое регулярное выражение для замены любых символов новой строки (и окружающих их пробелов )одним пробелом, если только эта строка не заканчивается на}
(с использованием отрицательного вида -позади ), затем, наконец, регулярное выражение для окончательного форматирования (переключить имя хоста и IP и удалить лишнюю запятую)
При этом символы новой строки игнорируются, и вы можете перенаправить результат в новый файл (или в существующий файл )с добавлением > your_new_filename
в конец. Это решение может использовать флаг -i
, чтобы изменить ваш файл на месте, если вместо этого вы сделали это:
perl -i -pe 's/(\w)\s*$/\1,\n/;' your_filename
perl -i -pe 'BEGIN{undef $/;} s/(?<!})\s*\n\s*/ /smg;' -e 's/(client )(\S+)(.*?)(\w+),\s*}/\1\4\3\2 }/g;' your_filename
Я бы сделал что-то вроде:
perl -0777 -pe 's{client\s+(\S+)\s*\{\s*(secret =.*)\s+shortname\s*=\s*(.*)\s*\}}
{client $3 { $2, ipaddr = $1 }}g'
Я уверен, что есть лучшие способы решить эту проблему, но я добился этого с помощью следующей комбинации sed
, awk
.
sed ':a;N;$!ba;s/\n/ /g' file | sed -e 's/ //g' -e 's/ client/\nclient/' | awk '{print $1" "$9" "$3" "$4" "$5" "$6", ipaddress "$8" "$2" "$10}'
Пояснение
sed ':a;N;$!ba;s/\n/ /g'
Заменить все новые строки пробелом. Обратитесь к этому этому ответу для получения дополнительной информации sed -e 's/ //g'
Чтобы заменить четыре блока с интервалом одним пробелом. -e 's/ client/\nclient/'
Добавить новую строку при совпадении клиентской строки. awk '{print $1" "$9" "$3" "$4" "$5" "$6", ipaddress "$8" "$2" "$10}'
Awk по умолчанию разделяет текст пробелами,поэтому здесь вам нужно только напечатать переменную имени хоста ($9 )и переменную IP-адреса ($2 )в нужном вам порядке. Вы можете отклонить переменную «shortname» ($7 )и жестко закодировать текст «ipaddress»