Find and replace everything between two placeholders with the contents of a variable

Aloha, I tried to figure out how to replace / insert text strings between two place holders.

#start
REPLACE ANYTHING IN HERE
#end

Initially, I tried to do this using BASH via sed, but hit the road block when I tried to pass the sed variable.

sed -n -i '/#start/{p;:a;N;/#end/!ba;s/.*\n/hello\n/};p' file.txt

Returns

#start
hello
#end

but without joy when I try

sed -n -i '/#start/{p;:a;N;/#end/!ba;s/.*\n/$replace_var\n/};p' file.txt

or

sed -n -i "/#start/{p;:a;N;/#end/!ba;s/.*\n/$replace_var\n/};p" file.txt

I was in this for hours and searched, but could not find a solution. I want to try python or another language, or maybe with awk. I am a little new in this world, so any useful information would be appreciated.

Thanks in advance

This is what I went with at the end. This is a script that, along with cron, updates the /var/etc/hosts.deny file with the latest ssh list published.

import re
import urllib2

hosts_deny = open('/etc/hosts.deny','r+')
hosts_deny_text = hosts_deny.read()

blockedHosts = urllib2.urlopen('http://www.openbl.org/lists/hosts.deny').read()
place = re.compile('(?<=#start)(\r?\n)'
                   '(.*?)'
                   '(?=\r?\n#end)',re.DOTALL)#DOTALL enables '.' to also include
                                             #a new line
hosts_deny_text = re.sub(place, '\n'+ blockedHosts, hosts_deny_text)
hosts_deny.seek(0)
hosts_deny.write(hosts_deny_text)
hosts_deny.close()
+5
source share
5 answers

, , :

import re

ss = '''qslkjqskqsdhf
#start
REPLACE ANYTHING IN HERE
#end
2135468761265
'''

reg = re.compile('(?<=#start)(\r?\n)'
                 '(.*?)'
                 '(?=\r?\n#end)',re.DOTALL)

print ss
print '----'
print reg.sub('\\1Ia orana',ss)

qslkjqskqsdhf
#start
REPLACE ANYTHING IN HERE
#end
2135468761265

----
qslkjqskqsdhf
#start
Ia orana
#end
2135468761265
+2

, :

sed -ie "/#start/,/#end/{/#start/b;/#end/b;s/.*/$replace_var/;}" file.txt

/#start/b /#end/b , .

+4

, sed , awk:

awk '!f; /#start/ { f=1; print repl } /#end/ { f=0; print }' repl="$replace_var" file.txt

f - , , . !f ({print $0}) , #start.

, eyquem:

cat << EOF > file.txt
qslkjqskqsdhf
#start
REPLACE ANYTHING IN HERE
#end
2135468761265
EOF

hello\nhello:

awk '!f; /#start/ { f=1; print repl } /#end/ { f=0; print }' repl="$(printf 'hello\nhello')" file.txt

:

qslkjqskqsdhf
#start
hello
hello
#end
2135468761265
+1

, :

sstart = s.split(start)
for i in range(len(s)):
   if i%2 ==1:
      send = sstart[i].split(end)
      for i in range(len(send)):
           if i%2 == 0:
                send[i] = REPLACEMENT
      sstart[i] = send.join()
s = sstart.join()

, , , .

0

With "dotall" regexp it is easy. It is easy with Perl, Python, PCRE, etc. For example, in Python:

>>> s = '''#start
... REPLACE ANYTHING IN HERE
... #end'''
>>> re.sub(r'(?s)(#start\n).*?\n(#end)',
           r'\1hello\n\2', s)
'#start\nhello\n#end'

Obviously, matching the start and end lines and replacing them alone is superfluous, but I decided to keep it in the general case if you want to expand it further.

I used (?s)instead of passing a flag re.DOTALL, so everything will be self-sufficient, and you won’t need to think about the differences between how to wrap Perl, Python, etc. flags. But in real life, it is usually better to read flags rather than embed them.

0
source

All Articles