0

I have a sed command I wish to run from within a bash script on a large xml file.

sed -i '/$OLD_IP_ADDRESS/!{q100};  {s/$OLD_GATEWAY/$NEW_GATEWAY/}'   $system_file 

where , if $OLD_IP_ADDRESS is present I substitute $OLD_GATEWAY for $NEW_GATEWAY (IPs) but $OLD_IP_ADDRESS if it is not present then I return 100

I am using the following from

Return code of sed for no match

as an example

kent$  echo "foo" | sed  '/foo/!{q100}; {s/f/b/}'
boo
kent$  echo $?
0

However when I run the command it removes the entire body of the xml and only leaves me with the header line

I have tried numerous variations of this but don't understand/see where I'm blanking the file.

I have searched but cant find info on this so any help would be most appreciated.

Zankrut Parmar
  • 1,872
  • 1
  • 13
  • 28
  • The above solution will work for a one line file, for 2 or more lines the solution will always fail unless every line is substituted. Go back to that solution and read on. – potong Feb 07 '19 at 12:04
  • Thank you for the pointer. I will investigate an awk alternative – islowey Feb 07 '19 at 12:11
  • 1
    Also you can't use single quotes if you want the shell to substitute the value of a variable. – tripleee Feb 07 '19 at 12:30
  • someone needs to post a guide to quotes that you're not allowed to write a shell script without understanding - misuse of quotes is by far the most common source of questions I see! [edit] your question to include concise, testable sample input (including values of those shell variables) and expected output so we can try to help you. – Ed Morton Feb 07 '19 at 14:29

1 Answers1

1

As @potong said, you can't use the q sed option in a multiline file, because it will ever fail unless every line has what you are searching for.

If you want to search if something is present or not, you can use grep before doing substitutions.

You can do something like that:

#!/bin/bash
if grep -q -e "${OLD_IP_ADDRESS}" "${system_file}"; then
   sed -i -e "s/${OLD_GATEWAY}/${NEW_GATEWAY}/" "${system_file}"
else
   exit 100
fi

This piece of code will substitute every first occurrence (g option not used) of ${OLD_GATEWAY} with ${NEW_GATEWAY} in every line only if ${OLD_IP_ADDRESS} is present at least once in the file.

If you need a oneliner you can use something like:

grep -q -e "${OLD_IP_ADDRESS}" "${system_file}" && sed -i -e "s/${OLD_GATEWAY}/${NEW_GATEWAY}/" "${system_file}"

being aware that the exit code will be different from 100.

ingroxd
  • 995
  • 1
  • 12
  • 28
  • Many Thanks !!! using#!/bin/bash if grep -q -e "${OLD_IP_ADDRESS}" "${system_file}"; then sed -i -e "s/${OLD_GATEWAY}/${NEW_GATEWAY}/" "${system_file}" old_ip_present=1 else old_ip_present=0 fi i was able to error check on the old_ip_present= part – islowey Feb 07 '19 at 14:25
  • Assuming OLD_IP_ADDRESS, etc. are actually IP addresses, you'd need to escape the `.`s` in them and anchor them to avoid false matches. – Ed Morton Feb 07 '19 at 14:30