1

并感谢您考虑我的问题!

我有这种格式的 nagios 配置文件:

define host{
    use             generic-camera
    host_name       camera_7
    alias           camera facing the 7th door at headquarters
    address         172.16.202.21
    parents         hq_switch
    hostgroups      cameras,fixed-cameras
    }

我想要完成的是使用 sed 匹配 IP 地址,并将文本附加到它之前的行。我已经看到很多建议如何将文本附加到与正则表达式匹配的行,但没有看到如何附加到前一个。我想将地址下列出的 IP 的 MAC 地址附加到别名行。这就是我希望在 sed 运行后需要注意的事项:

define host{
    use             generic-camera
    host_name       camera_7
    alias           camera facing the 7th door at headquarters MAC 00:01:02:aa:bb:cc
    address         172.16.202.21
    parents         hq_switch
    hostgroups      cameras,fixed-cameras
    }

它需要匹配 IP 的原因是 bash 脚本可以从其地址中获取设备的正确 MAC。

我也有可用的 awk,如果这是 awk 比 sed 写得更干净的情况。

感谢您的建议。

4

4 回答 4

0

使用 awk:

awk 'NR>1{if ($0 ~ "^ *address") print x " MAC 00:01:02:aa:bb:cc"; else print x};
   {x=$0} END{print x}' in-file

编辑:通过脚本而不是硬编码从 IP 地址获取 Mac 地址:

awk 'NR>1{if ($0 ~ "^ *address") {"arp "$2 | getline line; split(line, tok, " ");
    print x " MAC " tok[4];} else print x};{x=$0} END{print x}' in-file
于 2013-03-08T20:49:19.077 回答
0

使用sed

sed -n '
  ## Set label 'a'.
  :a

  ## Read and save every line until we find the IP.
  /172\.16\.202\.21/! { 
    N
    ba 
  }

  ## Append the MAC just before the last '\n' (previous line).
  s/^\(.*\)\n/\1 MAC 00:01:02:aa:bb:cc\n/

  ## Print all saved until now.
  p

  ## Remove all printed.
  s/^.*$//

  ## Enter a loop to save all content until end of file.
  :b
  $! { 
    N
    bb 
  }

  ## Remove the additional '\n' added by the 'N' command and print.
  s/\n//
  p

' infile

它产生:

define host{
    use             generic-camera
    host_name       camera_7
    alias           camera facing the 7th door at headquarters MAC 00:01:02:aa:bb:cc
    address         172.16.202.21
    parents         hq_switch
    hostgroups      cameras,fixed-cameras
    }
于 2013-03-08T20:51:02.497 回答
0

我觉得不需要转义 IP 地址字段中的点,文件中没有位置会包含不是 IP 地址的长字符串,所以我只是撕掉了 . 匹配以简化我的事情。shell 脚本加上我请求帮助的 sed 行如下所示:

#!/bin/bash
for (( h = 200; h <= 204; h++ ))
do
for (( j = 1; j <= 150; j++ ))
do
i="172.16.$h.$j"
mac=`grep $i\  /proc/net/arp |awk '{print $4}'`

sed "/alias/{N; /[^0-9]$i\$/s/\n/ MAC $mac&/;}" $1 >> ${1}.new1
done
done

grep -A4 -B4 MAC ${1}.new1 > ${1}.new2
sed -i "s/^--//g" ${1}.new2

sed -n -e '1,/host/p' /usr/local/nagios/etc/objects/${1} |sed '$d' > ${1}.top
grep -B4 -A999 HOST\ GROUP\ DEF /usr/local/nagios/etc/objects/${1} > ${1}.tail

mkdir -p new
cat ${1}.top ${1}.new2 ${1}.tail > new/${1}

我确信有更清洁的方法可以做同样的事情,但这是我必须使用我目前(公认的低水平)技能的工作。特别是,每个输出文件仅更改 1 个主机,有时每个文件有数百个,因此将它们全部拆分,仅更改数百个主机中的 1 个,然后 grepping 将单个更改吐到其他地方应该是清理了,但如果其他人最终解决了这个问题,这应该可以工作,至少它对我有用,但 YMMV。

于 2013-03-10T13:37:17.413 回答
0

另一个 sed 尝试:

sed '/alias/{N; /[^0-9]172\.16\.202\.21$/s/\n/ MAC 00:01:02:aa:bb:cc&/;}' file
于 2013-03-09T12:38:32.893 回答