2

How do I replace a string between two delimiters?

Some of the answers I found are close, but I think my need is a little more complex.

I.e. smb.conf contains a blank line between shares. I want to target the share I want to update. The first delimiter is "[sharename]" and the end delimiter can be a blank line.

I want to find and replace "writable = yes" with "writable = no" which may be inexactly formatted because of white space, but must occur between my two delimiters.

1
  • Maybe look into augeas.
    – Sven
    Jun 18, 2018 at 20:31

4 Answers 4

1

Almost there, thanks to this list and http://fahdshariff.blogspot.com/2012/12/sed-mutli-line-replacement-between-two.html.

I am able on the command line to replace the "writeable" with "# writeable" and can do so without regard to the Y/N setting, I insert another line later on.

sed '/\[${share_name}\]/,/^$/{/\[${share_name}\]/n;/^$/!{s/writeable/\#writeable/g}}' \
< ${input_file} \
> /tmp/parse-smb.tmp

While this works on the command line with the "!" escaped "!" it doesn't work in a script file, /bin/sh. I have to remove the escape but then the trigger doesn't hit.

Shell subtleties.

1

Ah, the "!" was fine, it was the failure of the "share_name" variable to translate. Use double rather than single quotes in this command.

sed "/\${share_name}\]/,/^$/{/[${share_name}\]/n;/^$/!s/writeable/\#writeable/g}}" \
< ${input_file} \
> /tmp/parse-smb.tmp

Should have realized that the subsequent line also used double quotes.

sed -i "s/\[${share_name}\]/\[${share_name}\]\n\thosts allow = 10.50.157.0\/24 \n\twriteable = no/" \
/tmp/parse-smb.tmp
0

I'd consider perl: untested

perl -00 -pe '/^\[your_share_name\]/ and s/writable\s*=\s*\Kyes/no/si' smb.conf
0

I think this is a job for perl (or python if you're so inclined.)

iMac$ cat ./replace.pl
#!/usr/bin/perl

while (<>) {
    if (/^\n/) { $replace = 0; }
    if (/\[share3\]/) { $replace = 1; }
    print unless /writable/;
    if (/writable/) {
    if ($replace == 1) {
        print "  writable = no\n";
    }
    else {
        print;
    }
    }
}
iMac$ cat smb.conf 
[share1]
  writable = yes
  user = anonymous
  host = remote

[share2]
  writable = yes
  user = anonymous
  host = remote

[share3]
  writable = yes
  user = anonymous
  host = remote

[share4]
  writable = yes
  user = anonymous
  host = remote

[share5]
  writable = yes
  user = anonymous
  host = remote
iMac$ cat smb.conf | ./replace.pl
[share1]
  writable = yes
  user = anonymous
  host = remote

[share2]
  writable = yes
  user = anonymous
  host = remote

[share3]
  writable = no
  user = anonymous
  host = remote

[share4]
  writable = yes
  user = anonymous
  host = remote

[share5]
  writable = yes
  user = anonymous
  host = remote

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .