我想从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";
}
答案 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 }'