使用sed将文本追加到前一行的末尾

使用sed将文本追加到前一行的末尾,sed,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

谢谢你考虑我的问题

我有以下格式的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更干净

感谢您的建议。

使用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地址:
使用
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
    }
另一种方法是:

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

我不觉得有必要避开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}
#/bin/bash
对于((h=200;h${1}.new1
完成
完成
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新
cat${1}.top${1}.new2${1}.tail>new/${1}

我相信有更干净的方法可以做到这一点,但这就是我目前的工作(公认的低水平)技能。特别是,每个输出文件只更改一个主机,有时每个文件有数百个,因此,在数百个主机中只有一个主机更改的情况下将它们全部拆分出来,然后再将单个更改放到其他地方,这种情况应该得到清理,但如果其他人最终出现此问题,至少应该可以这样做它为我做了,但是YMMV。

谢谢,这看起来会起作用,尝试将它与bash一起编写脚本,以获得具有相应IP的正确mac。我很兴奋这有多短,但由于我的描述,它不起作用。基本文件有数百个主机和IP,它会为每个IP放置相同的mac。我相信但是,将正则表达式从($0~“^*地址”)更改为更具体的($0~”172.16.202.21)它应该可以工作。@user2149818:如果你必须处理大量的IP地址,那么我建议你使用arp命令获取他们的Mac地址,然后按照我上面的建议附加它。我认为我们的shell可能存在一些差异?当我运行你的编辑时,我得到“/bin/sh:172.16.202.21:未找到”对于原始文件中的每个IP地址。我一直在做类似的工作,但它一次只对IP有效,而不是每个IP.awk“NR>1{if(\$0~\“^address*${I}\$\”)print x\'MAC${MAC}\“else print x};{x=\$0}END{print x}”在这个文件中,它工作得非常好,我能够将它合并到一个shell脚本中,将MAC地址与IP地址匹配,非常感谢!
#!/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}