使用sed将文本附加到上一行的末尾

时间:2013-03-08 20:27:45

标签: sed

感谢您考虑我的问题!

我有这种格式的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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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
    }

答案 2 :(得分:0)

另一个尝试尝试:

sed '/alias/{N; /[^0-9]172\.16\.202\.21$/s/\n/ MAC 00:01:02:aa:bb:cc&/;}' file

答案 3 :(得分: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个主机,有时每个文件有数百个,因此只需更改数百个主机中的一个就可以将它们全部拆分出来,然后将该单个更改用于在其他地方吐出来应该是清理了,但是如果其他人最终得到这个问题,这应该有用,至少它对我而言是YMMV。