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