如何从dhcpd.conf中删除租约?

时间:2018-11-23 10:03:23

标签: linux bash perl awk

我想从dhcpd.conf删除租约,在那里我给出要从Bash变量中删除的IP地址。按钮上有一个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 :(得分:3)

  

有人能看到我在做什么吗?

两件事。

首先,您要一次性读取整个文件(使用-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\\";
}

似乎有效的方法:-)

答案 1 :(得分:3)

基于@Kubator的awk answer

# 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";
}

答案 2 :(得分:2)

如果您想使用AWK解决方案:

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

将包含IP地址的BASH变量传递给AWK的解决方案:

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

正如您在上面所看到的,您必须避免每次出现点(通过bash变量替换${var//./\\.}来完成),这与您在PERL中所做的类似,因为它是regexp的一部分。

测试:

$ 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";
}

答案 3 :(得分:2)

问题:

  • 您正在打印全部或不打印。而是使用s///除去不需要的部分,然后无条件打印(例如,使用-p代替-n)。
  • .与换行符不匹配。通过使用/s可以解决此问题。
  • -l-0777没有任何意义(但也没有伤害)。

已修复:

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

附加更改:

  • 添加了两个/^/m,以限制事物可以匹配的位置,以加快事物的运行速度,并在出现其他地方的}故障时停止运行。
  • 删除了}之后的换行符。
  • \Q\E周围添加了$ip,以确保该值在字面上匹配。

答案 4 :(得分:1)

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定义为单个字符。

答案 5 :(得分:1)

您的数据具有规则的结构。在这种情况下,我总是使用...(范围)运算符:

#!/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 }'