使用sed从字符串中提取多个子字符串

时间:2013-09-12 07:50:22

标签: regex bash sed awk cocos2d-x

我正在开发一个cocos2dx项目,最近我们更新到了最新版本的cocos2dx,这引入了一些我正在清理的警告。

我有很多代码,如:

CCPoint somePoint = ccpAdd(this->getPosition(), _someRandomOffset);

不推荐使用ccpAdd方法,而选择+运算符,我想替换这样的实例。我尝试在google上搜索,但我无法找到如何使用sed提取两个字符串并将它们重新组合在一起。

CCPoint somePoint = this->getPosition() + _someRandomOffset;

我的问题是,如何使用针对我的源文件的某些脚本自动执行此替换?

如果sed命令可以处理嵌套的ccpAdd命令,则加分;例如:

CCPoint somePoint = ccpAdd(this->getPosition(), ccpAdd(one, two));

或许sed是错误的工具?

3 个答案:

答案 0 :(得分:1)

我认为

sed 's/ccpAdd(\(.*\),\(.*\))/\1+\2/g'

诀窍。

但是这不适用于嵌套事件,并且会在单行上多次出现模式时产生奇怪的结果。

不幸的是sed doesn't have non-greedy operators,所以第二个问题必须通过切换到另一个工具来解决,比如perl

perl -pe 's|ccpAdd\((.*?),(.*?)\)|\1 + \2|g'

为了使嵌套正确,您可以多次重新运行相同的perl命令,直到没有更多匹配(这是因为非贪婪的运算符)。

答案 1 :(得分:1)

中使用模块pyparsing并具有递归性的替代方法:

假设infile的内容为:

CCPoint somePoint = ccpAdd(this->getPosition(), _someRandomOffset);
CCPoint somePoint = ccpAdd(this->getPosition(), ccpAdd(one, two));

并且script.py为:

from pyparsing import *

parser = Forward()
parser << Literal('ccpAdd').suppress() \
    + Literal('(').suppress() \
    + ( parser | OneOrMore(CharsNotIn(',')) ) \
    + Literal(',').suppress() \
    + ( parser | OneOrMore(CharsNotIn(',)')) ) \
    + Literal(')').suppress()

parser.setParseAction(lambda t: ' + '.join(t))

with open('infile', 'r') as f:
    for line in f:
        r = parser.transformString(line)
        print(r, end='')

像以下一样运行:

python3 script.py

产量:

CCPoint somePoint = this->getPosition() +  _someRandomOffset;
CCPoint somePoint = this->getPosition() + one +  two;

答案 2 :(得分:-1)

我要做的是使用

sed 's/regex to match the old string/new string/'

然后将其写入文件。所以它会是这样的:

sed 's/regex to match the old string/new string/' > file

并且只提供sed输入只是重定向cat的标准输出:

cat thefile.txt | sed ...