Reputation: 1406
In my prog I need to, using sed, replace some characters with one another one in some file. But between some words and only if this string contains some extra word. So I wrote:
sed -re '/from:/,/end/ { /extraword/s/[_old_characters_]/new_character/g; }'
But this code totaly ignors this /from:/,/end/
strings. It replaces all [_old_characters_]
with new_character
starting from from:
and to the end of this line. What have I done wrong?
What I need is:
sed -re '/A/,/B/ { /word/s/[C]/X/g; }'
file:
word CCC A CCC B CCC
wor A CCC B
becomes:
word CCC A XXX B CCC
wor A CCC B
Upvotes: 1
Views: 108
Reputation: 58351
This might work for you (GNU sed):
sed -r '/word/{:a;/(A)([^ABC]*C+[^ABC]*)(B)/{s//\1\n\2\n\3/;h;y/C/X/;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/;ba}}' file
This filter lines which contain the word word
and A
followed by C
followed by B
. Such lines then have markers (\n
's) placed after A
and before B
and a copy of the line is placed in the hold space (HS). All C
's are replace with X
's and then the copy in the HS is appended to the amended line and the required line is rebuilt from both. The new line is then tested again and if necessary the procedure is repeated.
If A
and B
are words then use the same technique but substitute \n
after A
and before B
first, then test for /\n.*C.*\n/
remembering to remove all \n
's if the condition is not met.
Upvotes: 2
Reputation: 1542
In case using sed
proves too ugly, here's a Perl
solution:
$ perl -pe 'if (m/word/) {s/(A[^C]*) (.*) ([^C]*B)/$1 . " " . "X" x length($2) . " " . $3/gei;}'
word CCC A CCC B CCC
word CCC A XXX B CCC
wor A CCC B
wor A CCC B
Upvotes: 1
Reputation: 26667
Something like
sed '/^word/s/A CCC B/A XXX B/g'
eg
>>> echo word CCC A CCC B CCC | sed '/^word/s/A CCC B/A XXX B/g'
word CCC A XXX B CCC
Upvotes: 0