Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given the text example:

.... text ,..
string1 = 'abcde'
string2 = '12345'
.... 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. – stardiviner May 30 '12 at 14:56
I found a little hints: awk '/[{]{3}/,/[}]{3}/ { gsub(...)) }' file. But I still can not solve this problem. – stardiviner May 30 '12 at 15:28
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. – stardiviner May 31 '12 at 1:39
I have found out the correct solution: sed -i '/\s*{{{/,/\s*}}}$/s/\[\(\[[^]]*\]\)\]/\1/g' eg.txt – stardiviner 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 ? – stardiviner 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

#!/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 >

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
"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 ? – stardiviner 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

You must log in to answer this question.

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