There nginx config.

upstream { server 1.1.1.1:8080; server 2.2.2.2:8080 backup; } server { ... 

You must move the word backup from 2.2.2.2 to 1.1.1.1 and vice versa, using sed. For example, if:

 server 1.1.1.1:8080 backup; server 2.2.2.2:8080; 

do:

 server 1.1.1.1:8080; server 2.2.2.2:8080 backup; 

and if:

 server 1.1.1.1:8080; server 2.2.2.2:8080 backup; 

do:

 server 1.1.1.1:8080 backup; server 2.2.2.2:8080; 

How is this possible to do?

Addition: It is not known in advance where the backup will be located. Static information is only the IP address 1.1.1.1 and 2.2.2.2 .

  • instead of moving, consider the problem as “add where 1.1.1.1 and remove where 2.2.2.2 ” ... the overall complexity of the script will depend on the options for the diversity of configs ... - Fat-Zer
  • If you consider the solution to remove and add, then you can as follows: sed -e s/backup//g -e s/"1.1.1.1:8080"/"1.1.1.1:8080 backup"/g But as I said earlier, it is not known where will be located backup - Vitaliy Kalyuzhnyak

2 answers 2

In the simplest version, if you don’t check that everything is inside the upstream section and when nothing can stand in this line, you can do something like this:

 sed -re 's/(server\s+1\.1\.1\.1:8080).*/\1 backup.*;/;s/(server\s+2\.2\.2\.2:8080)\s+backup;/\1/;' 

Moving the word back and forth can be considered as “add if it is not there and remove it otherwise”:

 sed -re '/server (1\.1\.1\.1|2\.2\.2\.2):8080/{s/\s*backup//;t;s/\s*;/ backup;/} 

A deeper analysis in case a backup will backup in both lines will require a separate reading cycle - something is possible on sed , but it will be easier to use perl 'ohm or awk .

  • Your example changes only for 1.1.1.1 , it will not work if the backup is after 2.2.2.2 - Vitaliy Kalyuzhnyak
  • @VitaliyKalyuzhnyak, so it is necessary to "turn on in 1.1.1.1 and turn off in 2.2.2.2" or "throw from 2 to 1 or back"? - Fat-Zer
  • There is one goal, if there is a backup in 1.1.1.1 , then remove, and if there is no backup in 2.2.2.2 , then add - Vitaliy Kalyuzhnyak
  • @VitaliyKalyuzhnyak, um ... the question is exactly the opposite ... something I finally stopped understanding what you want ... - Fat-Zer
  • Yes, I apologize, the question is not fully correct. Added the most detailed description! - Vitaliy Kalyuzhnyak

subchask:

  1. add \ backup characters to the line containing the text 1\.1\.1\.1 , after this text, immediately before the character ; :

     $ sed '/1\.1\.1\.1/s/1\.1\.1\.1[^;]*/& backup/' file 
  2. remove \ backup characters from the line containing the text 2\.2\.2\.2 , after this text, but before the character ; :

     $ sed '/2\.2\.2\.2/s/\(2\.2\.2\.2[^;]*\) backup/\1/' file 

You can also use one command, separating programs with a semicolon:

 $ sed '/1\.1\.1\.1/s/1\.1\.1\.1[^;]*/& backup/;/2\.2\.2\.2/s/\(2\.2\.2\.2[^;]*\) backup/\1/' file 

if a “trigger” is required, removing the \ backup characters, if they were, and adding otherwise, you can add a conditional branch command t :

 $ sed '/1\.1\.1\.1/{s/\(1\.1\.1\.1[^;]*\) backup/\1/;to;s/1\.1\.1\.1[^;]*/& backup/};:o' file 

similarly for the line containing the text 2\.2\.2\.2 . if you combine it into one command, then the label :o you must leave only one:

 $ sed '/1\.1\.1\.1/{...};/2\.2\.2\.2/{...};:o' file 
  • This solution is suitable if we know in advance where backup , but the trouble is that we don’t know. - Vitaliy Kalyuzhnyak
  • supplemented the answer. - aleksandr barakin