简体   繁体   中英

bash/sed - adding multiple lines at specific location in file

I want to automate adding new backends to a configuration file and can't figure out how to do it. The relevant part of the file looks like this:

[backend]
backends = backend-1 backend-2
timeout = 10
connectionsperhost = 100

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3 

I'm looking for a simple solution to add another backend entry with a specific url and secret.

[backend-3]
url = https://adiffrentdomain.com
secret = 42349234238423424

and at the same time append the name "backend-3" to the line "backends = " at the "[backend]" section.

Is there a way to make this work with sed or bash scripting in genereal?

kindly appreciate any help or hints!

You can try an approach with awk . It adds a backends entry to lines starting with backends and attaches a [backend-x] section with the given info at the end of the file.
Obviously it relies on the entries of the backends being correct since it doesn't count the [backend] sections individually.

url="www.domain.com"
s=9283283h4923h42934

% awk -v url=$url -v s=$s '/^backends/{x=NF-1; $0=$0" backend-"x} 
    {print} 
    END{ print "\n[backend-"x"]\nurl = "url"\nsecret = "s }' file
[backend]
backends = backend-1 backend-2 backend-3
timeout = 10
connectionsperhost = 100

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3 

[backend-3]
url = www.domain.com
secret = 9283283h4923h42934

Data

cat file
[backend]
backends = backend-1 backend-2
timeout = 10
connectionsperhost = 100

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3 

Using sed

$ sed '/backends =/s/$/ backend-3/;/^\[backend-2/{N;N;s|secret.*|&\n\n[backend-3] \
url = https://adifferentdomain.com \
secret = 42349234238423424|}' input_file
[backend]
backends = backend-1 backend-2 backend-3
timeout = 10
connectionsperhost = 100

[backend-1]
url = https://somedomain.com
secret = 6135bcb7849ca1886e2de193

[backend-2]
url = https://anotherdomain.com
secret = 75048ad646a5af787cbbaaa3

[backend-3]
url = https://adiffrentdomain.com
secret = 42349234238423424

If the input is coming from variables, you would want to use double quotes instead to expand the variables. Eg;

sed "/backends =/s/$/ backend-3/;$a\\n[backend-3] \
url = $url_input \
secret = $secret_input" input_file

With awk for an arbitrary new backend entry with newbackendname , url and secret being the only provided inputs. Simply adds the new backend to the backends = -list and the corresponging block directly after the general [backend] -block.

awk -vnewentry="newbackendname" -vurl="http://new.url" -vsecret="secret123" '
  #in backends= line: add new entry (at first position)
  #and set `add` marker
  /^backends =/{sub(/^backends = /,"&"newentry" ",$0) ; add=1}
  #marker exists and empty line (end of header block) is found:
  #print new entry and unset marker `add`
  add && /^$/{ print "\n["newentry"]"
               print "url = "url
               print "secret = "secret
               add=0}
  #print by default
  1' infile.txt

Hopefully the comments make it easy to follow. With this code, you may as well just add url and secret via shell variables as awk -vurl="$URL" -vsecret="$SECRET" -vnewentry="$NEWBACKEND" '...' infile.txt

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM