Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question
    
Is there any text outside these delimiters? Anything else? –  slhck May 30 '12 at 12:44
    
Yes, there are text outside of those delimiters. –  NagatoPain May 30 '12 at 14:56
    
I found a little hints: awk '/[{]{3}/,/[}]{3}/ { gsub(...)) }' file. But I still can not solve this problem. –  NagatoPain May 30 '12 at 15:28

3 Answers 3

up vote 3 down vote accepted

This might work for you:

sed -i '/\s*{{{/,/\s*}}}$/s/\[\(\[[^]]*\]\)\]/\1/g' file.txt
share|improve this answer
    
sorry for this, I have not declare that maybe there is space or tab before {{{ and }}}, so ^ should be changed into \ * and something else. –  NagatoPain May 31 '12 at 1:39
    
I have found out the correct solution: sed -i '/\s*{{{/,/\s*}}}$/s/\[\(\[[^]]*\]\)\]/\1/g' eg.txt –  NagatoPain May 31 '12 at 3:01
    
@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 May 31 '12 at 8:44

This should work:

awk '/{{{/,/}}}/ { gsub(/\[\[/,"[");gsub(/\]\]/,"]") } { print }'
share|improve this answer
    
how to write result into original file directly ? –  NagatoPain May 31 '12 at 1:18
    
I don't think that awk supports in-place editing; you can write a simple shell script for that. –  cYrus May 31 '12 at 7:11

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.

share|improve this answer
    
'with sed or awk' –  corn3lius May 30 '12 at 16:44
1  
"Maybe sed or awk is not the only way to do this?" Selective reading ... my goodness. –  mikebabcock May 30 '12 at 17:28
    
I do not know perl, this can work, but It can not write result to original file. can you improve it ? –  NagatoPain May 31 '12 at 2:50
    
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 May 31 '12 at 13:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.