Home > Net >  How to insert text after a certain string in a file with variables
How to insert text after a certain string in a file with variables

Time:05-06

I have these variables:

file_path="/home/dir/file.xml"
string="<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>"

This is the content of file.xml

<network>
  <name>br-ext</name>
  <forward mode='route'/>
  <bridge name='br-ext' stp='on' delay='0'/>
  <mac address='52:54:00:9f:a0:00'/>
  <ip address='10.10.1.11' netmask='255.255.255.0'>
    <dhcp>
      <host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
      <host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
      <host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
      <host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
      <host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
      <host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
      <host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
      <host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
    </dhcp>
  </ip>
</network>

I would like to add the $string right after the <dhcp> flag, something like this:

...
<dhcp>
      <host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
      <host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
...

I tried using sed "/\dhcp\/a $string $file_path" in my bash script with no success...

Does anyone know how I can achieve this?

CodePudding user response:

You are not too far:

sed -i "/<dhcp>/a \ \ \ \ \ \ ${string}" "${file_path}"
  • -i to change input file
  • /<dhcp>/ to select only dhcp open tag
  • (\ ) * 6 to indent string content

Result:

<network>
  <name>br-ext</name>
  <forward mode='route'/>
  <bridge name='br-ext' stp='on' delay='0'/>
  <mac address='52:54:00:9f:a0:00'/>
  <ip address='10.10.1.11' netmask='255.255.255.0'>
    <dhcp>
      <host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
      <host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
      <host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
      <host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
      <host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
      <host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
      <host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
      <host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
      <host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
    </dhcp>
  </ip>
</network>

CodePudding user response:

Using sed

$ sed  "/<dhcp>/{p;s|\( \ \).*|\1  $string|;}" file
<network>
  <name>br-ext</name>
  <forward mode='route'/>
  <bridge name='br-ext' stp='on' delay='0'/>
  <mac address='52:54:00:9f:a0:00'/>
  <ip address='10.10.1.11' netmask='255.255.255.0'>
    <dhcp>
      <host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
      <host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
      <host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
      <host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
      <host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
      <host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
      <host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
      <host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
      <host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
    </dhcp>
  </ip>
</network>

CodePudding user response:

Using bash and sed's a (append) command:

sed '/^[[:blank:]]*<dhcp>[[:blank:]]*$/a'$'\\\n'"$string" "$file_path"

CodePudding user response:

You could use a pattern to match the <dhcp> part and capture the leading spaces.

Then append the next string, substitute with the full match for the last pattern followed by a newline and the backreference to keep the same indenting.

From that point on, you can extend it with your own indenting.

sed "/^\([[:space:]]*\)<dhcp>/{N;s##&\n\1  $string#}" "$file_path"

Explanation

  • /^\([[:space:]]*\)<dhcp>/ Natch start of string, capture optional spaces and match <dhcp>
  • N Append the next line to the pattern space
  • s substitute
  • ## The last matched pattern (I have changed the delimiter of the substitute to #)
  • &\n\1 Replace with the full match, newline and a backreference to group 1 containing the indenting and add your own indenting

Output

<network>
  <name>br-ext</name>
  <forward mode='route'/>
  <bridge name='br-ext' stp='on' delay='0'/>
  <mac address='52:54:00:9f:a0:00'/>
  <ip address='10.10.1.11' netmask='255.255.255.0'>
    <dhcp>
      <host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
      <host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
      <host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
      <host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
      <host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
      <host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
      <host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
      <host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
      <host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
    </dhcp>
  </ip>
</network>

CodePudding user response:

try this

#! /bin/bash

file_path="$HOME/test.xml"
content="<host>b</host>"

c=$(echo $content | sed 's/\//\\\//g')
sed "/<\/dhcp>/ s/.*/${c}\n&/" $file_path

CodePudding user response:

strings="      STRING1...\n      STRING2...\n      ...\n" 
match="<dhcp>"  
awk -v m="$match" -v s="$strings" '{ print; if($1 == m) printf s }' input_file

<network>
  <name>br-ext</name>
  <forward mode='route'/>
  <bridge name='br-ext' stp='on' delay='0'/>
  <mac address='52:54:00:9f:a0:00'/>
  <ip address='10.10.1.11' netmask='255.255.255.0'>
    <dhcp>
      STRING1...
      STRING2...
      ...
      <host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
      <host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
      <host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
      <host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
      <host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
      <host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
      <host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
      <host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
    </dhcp>
  </ip>
</network>
  • Related