基本上我有一个DHCP服务器日志的输出,如下所示:
hardware ethernet 00:16:41:ef:9e:47;
client-hostname "mo-10";
hardware ethernet 00:11:25:73:20:a5;
client-hostname "mo-11";
hardware ethernet 00:11:25:73:20:a5;
client-hostname "mo-11";
hardware ethernet 00:11:25:73:20:a5;
client-hostname "mo-11";
hardware ethernet 00:16:41:ef:9e:47;
client-hostname "mo-10";
hardware ethernet 00:11:25:73:21:35;
client-hostname "mo-23";
每两行汇集在一起 - 第一行是网络上设备的MAC地址,第二行是主机名。我想取列表,并将每对行放入我的dhcp服务器的配置块中,如下所示:
host mo-10 {
hardware ethernet 00:16:41:ef:9e:47;
fixed-address 192.168.1.10;
}
主机之后的部分应与客户机主机名相同,硬件以太网块应相同,固定地址应始终为192.168.1.x,其中x是主机名中的数字(因此对于主机mo- 10 ip应该是192.168.1.10,mo-23应该是192.168.1.23等。)所有内容都应该用大括号括起来。另外还有很多重复的条目,我想删除。我试着用grep和awk搞砸了,但是我不太精通在bash中操作文本,这对我来说太复杂了。如果有人能提供一种方法来解决这个问题并解释它为何起作用,我会很高兴。
非常感谢。
答案 0 :(得分:3)
这是一种方法:
awk '
NR%2 { eth = $0; next }
{ gsub(/[";]/,""); map[$NF] = eth }
END {
for (host in map) {
split (host, t, /-/);
print "host " host " {\n\t" map[host], RS, "\tfixed-ethernet 192.168.1."t[2]";" RS "}"
}
}' file
host mo-10 {
hardware ethernet 00:16:41:ef:9e:47;
fixed-ethernet 192.168.1.10;
}
host mo-11 {
hardware ethernet 00:11:25:73:20:a5;
fixed-ethernet 192.168.1.11;
}
host mo-23 {
hardware ethernet 00:11:25:73:21:35;
fixed-ethernet 192.168.1.23;
}
将奇数行存储在变量eth
中。对于偶数行,删除引号和;
并创建一个键值为主机名的哈希值,其值为line。在END
块中,您遍历哈希并在-
上拆分主机名。
然后您只需打印所需的输出。
答案 1 :(得分:0)
你可以使用sed。要删除重复项,我建议使用管道:
sed '/hardware/{N;s/\n/ /}' < list | sort -k5 | uniq -f4 | sed -r 's/ *hardware ([^ ]*) ([^;]*); *.*"(.*\-(.*))";/host \3 {\n\thardware \1 \2;\n\tfixed-address 192.178.10.\4;\n}/'
管道将每行记录的两行记录展平为一行,然后将它们改为sort / uniq,然后重新发送sed以进行最终格式化。
输出:
host mo-10 {
hardware ethernet 00:16:41:ef:9e:47;
fixed-address 192.178.10.10;
}
host mo-11 {
hardware ethernet 00:11:25:73:20:a5;
fixed-address 192.178.10.11;
}
host mo-23 {
hardware ethernet 00:11:25:73:21:35;
fixed-address 192.178.10.23;
}
顺便说一句,毕竟我更喜欢awk
解决方案,因为它不需要一次又一次地迭代数据。 (在给出此答案的第一个版本时,没有阅读删除重复限制。)
答案 2 :(得分:0)
下一个:
perl -lanE '
if(/^\s*$/){$.--;next} #skip empty lines
push @v, map {s/[^\da-f:]//ig;$_} $F[$.%2+1] }{ %h=@v; #process
#print
say qq[host mo-$h{$_} {
hardware ethernet $_;
fixed-address 192.168.1.$h{$_};
}] for keys %h
' <<EOF
hardware ethernet 00:16:41:ef:9e:47 ;
client-hostname "mo-10" ;
hardware ethernet 00:11:25:73:20:a5;
client-hostname "mo-11" ;
hardware ethernet 00:11:25:73:20:a5 ;
client-hostname "mo-11";
hardware ethernet 00:11:25:73:20:a5;
client-hostname "mo-11";
hardware ethernet 00:16:41:ef:9e:47;
client-hostname "mo-10";
hardware ethernet 00:11:25:73:21:35;
client-hostname "mo-23";
EOF
打印
host mo-23 {
hardware ethernet 00:11:25:73:21:35;
fixed-address 192.168.1.23;
}
host mo-10 {
hardware ethernet 00:16:41:ef:9e:47;
fixed-address 192.168.1.10;
}
host mo-11 {
hardware ethernet 00:11:25:73:20:a5;
fixed-address 192.168.1.11;
}
答案 3 :(得分:0)
在Python中:
import re, sys
template='''\
host {} {{
hardware ethernet {}
fixed-address 192.168.1.{};
}}'''
pat=re.compile(r'hardware ethernet ([^;]+;)\nclient-hostname ([^;]+;)')
with open(sys.argv[1], 'r') as fin:
di={k.rstrip(';').strip('"'):v
for v, k in pat.findall(fin.read())}
for k, v in di.items():
ip=re.search(r'(\d+)$', k).group(1)
print template.format(k, v, ip)
从Bash开始,运行python ip.pl log.txt
打印:
host mo-23 {
hardware ethernet 00:11:25:73:21:35;
fixed-address 192.168.1.23;
}
host mo-11 {
hardware ethernet 00:11:25:73:20:a5;
fixed-address 192.168.1.11;
}
host mo-10 {
hardware ethernet 00:16:41:ef:9e:47;
fixed-address 192.168.1.10;
}
通过将主机名数据添加到dict来执行重复删除,该dict只能为每个键值提供一个值。