Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have some configuration files that basically look like

(...content...)
# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY
(... more content ...)
# END DYNAMIC BLOCK
(... even more content ...)

Now, in bash using CONTENT=`wget -O - http://$SERVER/get_config.php`, I have the replacement for the dynamic block.

How do I do the replace now and how do I make the script insert the block at file's end if it isn't there?

share|improve this question

2 Answers 2

up vote 5 down vote accepted

If you want to use sed, you can read from a named pipe:

tmp=$(mktemp -d)
(
  cd "$tmp"
  mkfifo dynamic
  wget -O dynamic "$CONTENT" & wget_pid=$!
  sed -e '/^# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY$/ p' \
      -e '/^# END DYNAMIC BLOCK$/ {' -e p -e 'r dynamic' -e '}' \
      -e '/^# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY$/, /^# END DYNAMIC BLOCK$/ d'
  kill $wget_pid
)
rm -rf "$tmp"

But I'd go for awk.

export CONTENT
awk '
    $0 == "# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY" {skip=1; next}
    $0 == "# END DYNAMIC BLOCK" {skip=0; system("wget $CONTENT")}
    !skip {print}
'
share|improve this answer
1  
+1 for the awk solution. Bonus for style. Very tight, clean and readable solution. Goes straight to my cheat sheet :) –  aktivb Jan 3 '13 at 9:01
1  
the awk-solution is... wow –  user1933738 Jan 3 '13 at 14:39

I would go with a sub-shell and two sed commands, something like this:

beg_tag='# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY'
end_tag='# END DYNAMIC BLOCK'

(
  sed "/^$beg_tag"'$/,$d' oldconf
  echo "$beg_tag"
  wget -O - http://$SERVER/get_config.php
  echo "$end_tag"
  sed "1,/^$end_tag/d" oldconf
) > newconf

Be careful not to put any sed-significant characters into beg_tag and end_tag.

This will append the output if no tags are present. The first sed command will never delete any lines from the input and the second sed command will delete all lines.

Testing

If oldconf contains:

(...content...)
# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY
(... more content ...)
# END DYNAMIC BLOCK
(... even more content ...)

And the wget command is replaced by echo hello world, the output is:

(...content...)
# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY
hello world
# END DYNAMIC BLOCK
(... even more content ...)

Now if the block is removed, i.e. the following input is used:

(...content...)
(... even more content ...)

The output is:

(...content...)
(... even more content ...)
# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY
hello world
# END DYNAMIC BLOCK
share|improve this answer
    
Thank you, works fine –  user1933738 Jan 3 '13 at 0:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.