0

I have a problem that is very similar to those SO thread:

Linux: How to replace all text between two lines and substitute it with the output of a variable using sed?

how to replace all lines between two points and subtitute it with some text in sed

On my scenario I have an template file like:

...
some code
...
// BEGIN CODE1
// END CODE1
...
some code
...
// BEGIN CODE2
// END CODE2
...
some code
...

The goal is update as needed the contents between CODE1 or CODE2 keeping those comments for future updates (read the script will be on cron Job updating it daily).

Since I'm on FreeBSD my sed dont have the parameters b or p like Linux does, could someone point me how to archive it?

For CODE1 basicaly will be store update the path for some include files.

Have tried this:

#!/bin/sh


directory="/path/to/list/files"

for file in "$directory"/*.txt
do
  if [ -f "$file" ]; then
    content=$(sed -n '/\/\/ BEGIN CODE1/{:a;N;/\/\/ END CODE1/!ba;p}' "$file")

    sed -i '' '/\/\/ BEGIN/,/\/\/ END/{//!c\
INCLUDE /tmp/test.txt
}' "/root/replace.txt"
  fi
done

But got this error:

sed: 1: "/\/\/ BEGIN/{:a;N;/\/\/ ...": unexpected EOF (pending }'s)

Desired output for CODE1 would be:

...
some code
...
// BEGIN CODE1
$INCLUDE "/usr/local/etc/namedb/keys/domain.com/ksk.key"
$INCLUDE "/usr/local/etc/namedb/keys/domain.com/zsk.key"
// END CODE1
...
some code
...
// BEGIN CODE2
// END CODE2
...
some code
...

But it need be dynamic, every time cron job runs will put an new path.

FolderKeys="/usr/local/namedb/keys"
FolderSites="/usr/local/etc/namedb/working"
declare -a Sites=( $(ls /$FolderSites | grep '.db$' | sed 's/.db$//') )

for Site in "${Sites[@]}"
do

    ls -la $FolderJail$FolderKeys/$Site/*.key

done

Real usage scenario:

I will have an Cron Job checking the $FolderKeys once time per day, and updating the contents daily between:

// BEGIN DNSSEC CODE

// END DNSSEC CODE

On file /usr/local/etc/namedb/working/domain.com.db

This is why I need keep the comments using sed or another tool for replace only the contents inside between:

// BEGIN DNSSEC CODE

// END DNSSEC CODE

For every domain without change other text from namedb zones.

Wisdom
  • 121
  • 1
  • 1
  • 13
  • Does it have to be sed? Are you willing to use another tool? – glenn jackman Jun 08 '23 at 14:51
  • @glennjackman Don't need be sed, was using it because other questions have an similar approach of the goal. – Wisdom Jun 08 '23 at 15:12
  • @anubhava Added an example of output, but its need be dynamic, and not hard coded, thats why cant remove the comments and those need still for next run of update. – Wisdom Jun 08 '23 at 15:13
  • Why do you think FreeBSD sed "dont have the parameters b or p" ? It has both. However labels extend to end of line. Don't use `;`, use separate lnes – jhnc Jun 08 '23 at 15:53
  • 1
    Sounds more like a job for awk than sed. @glennjackman Is that what you were thinking? – Victor Eijkhout Jun 08 '23 at 16:07
  • @jhnc using man sed the description and options at begin dont show those, but after read entire manual I saw they are at end. – Wisdom Jun 08 '23 at 16:58
  • I will update the question with real use caso for CODE1 – Wisdom Jun 08 '23 at 16:58
  • @VictorEijkhout: yep, I agree, definitively better to use `awk` than `sed` for this purpose. – Valery S. Jun 09 '23 at 05:35

1 Answers1

0

FreeBSD sed treats labels slightly differently than other seds. They extend to end of line and are not terminated by ;. So write your program using newlines instead of ; :

# ...
content=$(
    sed -n '
        /\/\/ BEGIN CODE1/{
            :a
            N
            /\/\/ END CODE1/!ba
            p 
        }
    ' "$file"
)
# ...
jhnc
  • 11,310
  • 1
  • 9
  • 26