Как удалить аренду из dhcpd.conf? - PullRequest
0 голосов
/ 23 ноября 2018

Я хотел бы удалить аренду из dhcpd.conf, где я даю IP-адрес, который нужно удалить из переменной Bash.Пример dhcpd.conf находится на кнопке.

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

ip="192.168.234.5"; perl -0777snle 'print if /lease $ip \{.*?\}/' -- -ip=$ip dhcpd.leases 

Используя Perl 5.16.3

Вопрос

Кто-нибудь может увидеть, что я делаю неправильно?

lease 192.168.234.5 {
  starts 3 2018/11/21 18:53:11;
  ends 3 2018/11/21 18:54:11;
  tstp 3 2018/11/21 18:54:11;
  cltt 3 2018/11/21 18:53:11;
  binding state free;
  hardware ethernet 14:99:e2:04:52:5c;
  uid "\001\024\231\342\004R\\";
}
lease 192.168.234.2 {
  starts 3 2018/11/21 20:42:48;
  ends 3 2018/11/21 20:52:48;
  tstp 3 2018/11/21 20:52:48;
  cltt 3 2018/11/21 20:42:48;
  binding state free;
  hardware ethernet 00:21:5e:90:13:fb;
  set MacAddress = "00:21:5E:90:13:FB";
  set output = "192.168.234.2,00:21:5E:90:13:FB,(host-decl-name n/a),5E9013FB,(dhcp-client-identifier n/a),(vendor-class-identifier n/a),(agent.remote n/a),(agent.circuit n/a)";
}
lease 192.168.234.13 {
  starts 3 2018/11/21 21:38:16;
  ends 3 2018/11/21 21:38:27;
  tstp 3 2018/11/21 21:38:27;
  cltt 3 2018/11/21 21:38:16;
  binding state free;
  hardware ethernet 00:e0:6f:11:7f:59;
  uid "\001\000\340o\021\177Y";
}

Ответы [ 6 ]

0 голосов
/ 25 ноября 2018

Проблемы:

  • Вы печатаете все или ничего.Вместо этого используйте s///, чтобы удалить ненужные детали, затем печатайте безоговорочно (скажем, с помощью -p вместо -n).
  • . не будет соответствовать переводу строки.Это исправлено с помощью /s.
  • -l не имеет смысла с -0777 (но и не повредит).

Исправлено:

perl -0777spe's/^lease \Q$ip\E \{.*?^\}\n//sm' -- -ip=$ip dhcpd.leases

Добавлены изменения:

  • Добавлена ​​пара /^/m для ограничения, где вещи могут совпадать, для ускорения вещей и остановки, если из-за сбоя в работе, если } найден в другом месте.
  • Удален перевод строки, следующий за }.
  • Добавлено \Q\E вокруг $ip, чтобы обеспечить буквальное совпадение значения.
0 голосов
/ 23 ноября 2018

Ваши данные имеют регулярную структуру.В таких случаях я всегда использую оператор ... (диапазон):

#!/usr/bin/perl
use strict;
use warnings;

my $ip    = "192.168.234.13";
my $regex = qr,^lease \Q${ip}\E \{$,;
while (<DATA>) {
    if (/$regex/.../^\}/) {
    # inside lease
    print "MATCHED $_";
    } else {
    print "OTHER   $_";
    }
}

__DATA__
lease 192.168.234.5 {
  starts 3 2018/11/21 18:53:11;
  ends 3 2018/11/21 18:54:11;
  tstp 3 2018/11/21 18:54:11;
  cltt 3 2018/11/21 18:53:11;
  binding state free;
  hardware ethernet 14:99:e2:04:52:5c;
  uid "\001\024\231\342\004R\\";
}
lease 192.168.234.13 {
  starts 3 2018/11/21 21:38:16;
  ends 3 2018/11/21 21:38:27;
  tstp 3 2018/11/21 21:38:27;
  cltt 3 2018/11/21 21:38:16;
  binding state free;
  hardware ethernet 00:e0:6f:11:7f:59;
  uid "\001\000\340o\021\177Y";
}

Пример вывода:

OTHER   lease 192.168.234.5 {
OTHER     starts 3 2018/11/21 18:53:11;
OTHER     ends 3 2018/11/21 18:54:11;
OTHER     tstp 3 2018/11/21 18:54:11;
OTHER     cltt 3 2018/11/21 18:53:11;
OTHER     binding state free;
OTHER     hardware ethernet 14:99:e2:04:52:5c;
OTHER     uid "\001\024\231\342\004R\\";
OTHER   }
MATCHED lease 192.168.234.13 {
MATCHED   starts 3 2018/11/21 21:38:16;
MATCHED   ends 3 2018/11/21 21:38:27;
MATCHED   tstp 3 2018/11/21 21:38:27;
MATCHED   cltt 3 2018/11/21 21:38:16;
MATCHED   binding state free;
MATCHED   hardware ethernet 00:e0:6f:11:7f:59;
MATCHED   uid "\001\000\340o\021\177Y";
MATCHED }

или в виде однострочного:

perl -ne 'if (/^lease 192\.168\.234\.13 \{$/.../^\}/) { print }'
0 голосов
/ 23 ноября 2018

gawk поставляется с многосимвольными разделителями записей:

gawk -v ip="${ip}" 'BEGIN{RS=ORS="}\n"} $0 !~ ip' dhcp.leases

Мы разбиваем входной файл на записи, разделенные }\n.Это безопасно, поскольку входной файл автоматически генерируется сервером dhcp и гарантированно не содержит новых строк и другого мусора.

Имея это, мы можем просто напечатать те записи, которые не соответствуют ip.


PS: Если вы готовы принять дополнительный пустой символ новой строки, который не повредит и случается только в случае удаления первой записи, вы можете использовать переносную команду POSIX awk:

awk -v ip="${ip}" 'BEGIN{RS=ORS="}"} $0 !~ ip' dhcp.leases

Примечание: POSIX определяет RS как один символ.

0 голосов
/ 23 ноября 2018

На основе ответа awk @ Kubator :

# perl -lnse '$f = 0 if /^lease/; $f = 1 if /^lease $ip [{]/; print if not $f;' \
       -- -ip=192.168.234.2 leases
lease 192.168.234.5 {
  starts 3 2018/11/21 18:53:11;
  ends 3 2018/11/21 18:54:11;
  tstp 3 2018/11/21 18:54:11;
  cltt 3 2018/11/21 18:53:11;
  binding state free;
  hardware ethernet 14:99:e2:04:52:5c;
  uid "\001\024\231\342\004R\\";
}
lease 192.168.234.13 {
  starts 3 2018/11/21 21:38:16;
  ends 3 2018/11/21 21:38:27;
  tstp 3 2018/11/21 21:38:27;
  cltt 3 2018/11/21 21:38:16;
  binding state free;
  hardware ethernet 00:e0:6f:11:7f:59;
  uid "\001\000\340o\021\177Y";
}
0 голосов
/ 23 ноября 2018

В случае, если вы хотите использовать решение AWK:

awk '/^lease/ { rem=0; } /^lease 192\.168\.234\.2/ { rem=1; } !rem' dhcpd.leases

Решение с передачей переменной BASH, содержащей IP-адрес, в AWK:

awk '/^lease/ { rem=0; } /^lease '${var//./\\.}'/ { rem=1; } !rem' dhcpd.leases

Как вы видите выше, вы должны выйти из каждоговхождение точки (это делается путем подстановки переменных bash ${var//./\\.}), аналогично тому, что вы делали в PERL, потому что является частью регулярного выражения.

Test:

$ var='192.168.234.2'
$ awk '/^lease/ { rem=0; } /^lease '${var//./\\.}'/ { rem=1; } !rem' dhcpd.leases
lease 192.168.234.5 {
  starts 3 2018/11/21 18:53:11;
  ends 3 2018/11/21 18:54:11;
  tstp 3 2018/11/21 18:54:11;
  cltt 3 2018/11/21 18:53:11;
  binding state free;
  hardware ethernet 14:99:e2:04:52:5c;
  uid "\001\024\231\342\004R\\";
}
lease 192.168.234.13 {
  starts 3 2018/11/21 21:38:16;
  ends 3 2018/11/21 21:38:27;
  tstp 3 2018/11/21 21:38:27;
  cltt 3 2018/11/21 21:38:16;
  binding state free;
  hardware ethernet 00:e0:6f:11:7f:59;
  uid "\001\000\340o\021\177Y";
}
0 голосов
/ 23 ноября 2018

Кто-нибудь может увидеть, что я делаю неправильно?

Две вещи.

Во-первых, вы читаете весь файл за один раз (с -0777), что означает, что вы теряете возможность легко распечатать один раздел из вашего файла.Лучше использовать -0175, что восьмерично для "}".Таким образом, ваш код выполняется один раз для каждого раздела во входном файле.

Но он все равно не работает.Это из-за вашего регулярного выражения - /lease $ip \{.*?\}/.Эта точка по умолчанию соответствует любому символу , за исключением новой строки .А так как ваши символы '{' и '}' всегда находятся на разных строках, это никогда не будет совпадать.

Вы можете добавить /s в конец оператора соответствия, чтобы изменить значение . чтобы соответствовать новой строке.Но я думаю, что проще просто усечь регулярное выражение, чтобы оно соответствовало только тому, что важно для вас - /lease $ip \{/.На самом деле, я бы добавил ^ к началу, просто чтобы быть действительно уверенным.

Итак, наконец, мы заканчиваем этим:

$ ip="192.168.234.5"; perl -0175snle 'print if /^lease $ip \{/' -- -ip=$ip dhcpd.leases
lease 192.168.234.5 {
  starts 3 2018/11/21 18:53:11;
  ends 3 2018/11/21 18:54:11;
  tstp 3 2018/11/21 18:54:11;
  cltt 3 2018/11/21 18:53:11;
  binding state free;
  hardware ethernet 14:99:e2:04:52:5c;
  uid "\001\024\231\342\004R\\";
}

, который, кажется, работает:-)

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