How to substitute multiple lines between delimiters

2

Given the text example:

.... text ,..
{{{python
string1 = 'abcde'
string2 = '12345'
print(string1[[1:3]])
print(string2[[:-1]])
}}}
.... text ,..

The [[ and ]] also appear outside of {{{ too. Maybe there are spaces and tabs before {{{ and }}}.

I want to substitute all [[ and ]] into [ and ] between {{{ and }}}.

I need to write the result back to original file.

How can I do this? Will sed or awk work?

stardiviner

Posted 2012-05-30T11:57:03.877

Reputation: 189

Is there any text outside these delimiters? Anything else? – slhck – 2012-05-30T12:44:55.993

Yes, there are text outside of those delimiters. – stardiviner – 2012-05-30T14:56:01.157

I found a little hints: awk '/[{]{3}/,/[}]{3}/ { gsub(...)) }' file. But I still can not solve this problem. – stardiviner – 2012-05-30T15:28:44.423

Answers

3

This might work for you:

sed -i '/\s*{{{/,/\s*}}}$/s/\[\(\[[^]]*\]\)\]/\1/g' file.txt

potong

Posted 2012-05-30T11:57:03.877

Reputation: 156

sorry for this, I have not declare that maybe there is space or tab before {{{ and }}}, so ^ should be changed into \ * and something else. – stardiviner – 2012-05-31T01:39:52.513

I have found out the correct solution: sed -i '/\s*{{{/,/\s*}}}$/s/\[\(\[[^]]*\]\)\]/\1/g' eg.txt – stardiviner – 2012-05-31T03:01:26.657

@chris Next time, please edit the answer to include the correct solution. People searching for something similar won't necessarily read the comments. Thank you! – slhck – 2012-05-31T08:44:05.900

2

I would use perl with a minor state variable. Assuming you saved the below as replace.pl:

#!/usr/bin/perl -w
my $inbraces=0;
while (<>) {
    /\{\{\{/ and $inbraces=1;
    $inbraces==1 && s/\[\[/[/;
    $inbraces==1 && s/]]/]/;
    /}}}/ and $inbraces=0;
    print $_;
}

You would want to run something like:

cat inputfile.txt | perl replace.pl > outputfile.pl

Basically, PERL loops over this for each line of input because of the while(<>) and for each line, if it matches the three-brace regex, it turns on and off whether the substitutions should take place. All the regexes are nearly identical to sed. Open braces are escaped when matching because of their keyword nature.

mikebabcock

Posted 2012-05-30T11:57:03.877

Reputation: 1 019

'with sed or awk' – corn3lius – 2012-05-30T16:44:47.457

1"Maybe sed or awk is not the only way to do this?"

Selective reading ... my goodness. – mikebabcock – 2012-05-30T17:28:27.127

I do not know perl, this can work, but It can not write result to original file. can you improve it ? – stardiviner – 2012-05-31T02:50:48.807

the above will output the modified lines exactly as sed or awk would, output redirection is up to the user; I'll modify with a sample command-line. Simply doing "cat a | filter > b; mv b a" will do what you want. – mikebabcock – 2012-05-31T13:15:07.120

2

This should work:

awk '/{{{/,/}}}/ { gsub(/\[\[/,"[");gsub(/\]\]/,"]") } { print }'

cYrus

Posted 2012-05-30T11:57:03.877

Reputation: 18 102

how to write result into original file directly ? – stardiviner – 2012-05-31T01:18:24.147

I don't think that awk supports in-place editing; you can write a simple shell script for that. – cYrus – 2012-05-31T07:11:50.797