sed中的匹配范围

时间:2014-10-08 18:09:38

标签: regex bash sed

在我的编程中,我需要使用sed在某个文件中将一些字符替换为另一个字符。但在某些单词之间,只有当这个字符串包含一些额外的单词时。所以我写道:

sed -re '/from:/,/end/ { /extraword/s/[_old_characters_]/new_character/g; }'

但是这段代码完全忽略了这个/from:/,/end/字符串。它将所有[_old_characters_]替换为new_character,从from:开始到此行的末尾。我做错了什么?

我需要的是:

sed -re '/A/,/B/ { /word/s/[C]/X/g; }'

文件:

word CCC A CCC B CCC
wor A CCC B

变为:

word CCC A XXX B CCC
wor A CCC B

3 个答案:

答案 0 :(得分:2)

这可能适合你(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

此过滤行包含单词wordA后跟C后跟B。然后,这些行在\n之后和A之前放置标记(B),并将该行的副本放置在保留空间(HS)中。所有C都替换为X,然后HS中的副本将附加到修改后的行,并从两者重建所需的行。然后再次测试新生产线,如有必要,重复该过程。

如果AB是单词,那么请使用相同的技术,但在\n之后和A之前替换B,然后测试{{1}如果条件不满足,请记住删除所有/\n.*C.*\n/

答案 1 :(得分:1)

如果使用sed证明过于丑陋,可以使用Perl解决方案:

$ 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

答案 2 :(得分:0)

这样的东西
sed '/^word/s/A CCC B/A XXX B/g'

例如

>>> echo word CCC A CCC B CCC | sed '/^word/s/A CCC B/A XXX B/g'
word CCC A XXX B CCC