Woking on block of text with sed while changed delimiter

I have curious issue that I can't figure out...

Lets say we have variable:

_file="/var/log/messages"

and file containing also this block:

/var/log/secure /var/log/messages /var/log/cron /var/log/maillog {
    compress
    monthly
    rotate 6
    create 600
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/*syslog*.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

I need a sed command that would select this specific block which contain the $_file at the start and ending with } and than do something in it.... lets say remove the $_file from it..

First issue is that its path so we need to change delimiter in sed

 sed -e "s|$_file[[:space:]]||" tests_file.txt

above will work, but I need to specify the block, normally it should look like:

sed -e "|$_file|,|\}|{s|$_file[[:space:]]||}"

but that always fail with:

sed: -e expression #1, char 1: unknown command: `|'

Any idea whats going on ?


With s you can choose a delimiter in a straightforward way. It can be

s/a/b/
s|a|b|
sxaxbx

The chosen character must be a single-byte character though.

When specifying regex as an address, it's somewhat less straightforward:

/regex/
\cregexc

where c is any single-byte character. This means if you choose |, you need to escape it before regex, but not after.

sed -e "\|$_file|,\|\}|{s|$_file[[:space:]]||}" tests_file.txt
#       ^   here  ^

This works with GNU sed in my Debian 9.


Your example is unfortunate though. A line with $_file is always within a block therefore s will always affect it. This is because if you try to put $_file outside of the block, it will start a new block.

More educative example:

sed -e "\|$_file|,\|\}| s|a|X|g" tests_file.txt

This will change every a to X within a block. If you put a line containing a outside of any block, it will not be affected. (Note I dropped { and } embracing s. In this simple case they are not needed.)


The '/'es in your _file variable confuse sed as it uses the '/' as a delimiter for the addresses as well as the substitute delimitors.
You need to change the delimiter (e.g. to | ) whereby the first delimiter of each address must be escaped (like this \|) :

sed -e "\|.*$_file .*{$|,\|^}$|s|$_file ||" test_file.txt