我有大量的源文件,其ctor初始化如下:
Foo::Foo(...) : Bar("CamelCaseArgument") {}
我必须用CAMEL_CASE_ARGUMENT替换“ CamelCaseArgument”
所以结果应该是
Foo::Foo(...) : Bar(CAMEL_CASE_ARGUMENT) {}
Foo和CamelCaseArgument有所不同,Bar是一个类名,因此它始终相同,可以用作模式元素,
可以使用python / perl / php / etc轻松完成此任务,但我很好奇是否可以使用sed处理, 我最初的想法是在两轮中使用gnu sed,
1)删除“字符”,
$ echo 'Foo::Foo() : Bar("CamelCaseArgument") {}' | sed -rne 's/(Bar.{1})(["])([[:alpha:]]*)(["])/\1\3/gip'
Foo::Foo() : Bar(CamelCaseArgument) {}
2)转换CamelCaseArgument => CAMEL_CASE_ARGUMENT
我不知道如何输出所有匹配的部分,而不仅仅是最后一个
我当前的(无效)公式:
$ echo 'Foo::Foo() : Bar(CamelCaseArgument) {}' | sed -rn 's/Bar.{1}([A-Z][a-z]*)+/\0\U\1_/gp'
Foo::Foo() : Bar(CamelCaseArgument_ARGUMENT) {}
答案 0 :(得分:3)
perl -pe '
s{"((?:[[:upper:]][[:lower:]]+){2,})"}{
join "_", map {uc} ($1 =~ /[[:upper:]][[:lower:]]+/g)
}eg
' <<END
Foo::Foo(...) : Bar("CamelCaseArgument") {}
END
Foo::Foo(...) : Bar(CAMEL_CASE_ARGUMENT) {}
如果要过滤Bar
,请使用此正则表达式:
Bar\(\K"((?:[[:upper:]][[:lower:]]+){2,})"
答案 1 :(得分:2)
sed不适用于此类复杂任务,而应使用perl,awk等。既然您需要一种sed解决方案,但没人想出一个解决方案,但我要分享这种解决方法。
$ cat file
Foo::Foo(...) : Bar("CamelCaseArgument") {}
Foo::Foo(...) : Bar("ThisIsATest") {}
Foo::Foo(...) : Baz("ThisIsATest") {}
Foo::Foo(...) : Bar("Camel") {}
Foo::Foo(...) : Bar("") {}
$
$ cat tst.sed
s/\<Bar("/Bar(\n/; t1; b
:1
s/\n\([A-Z][a-z]*\)/\U\1_\n/; t1
# clean up
s/_\?\n"//
$
$ sed -f tst.sed file
Foo::Foo(...) : Bar(CAMEL_CASE_ARGUMENT) {}
Foo::Foo(...) : Bar(THIS_IS_A_TEST) {}
Foo::Foo(...) : Baz("ThisIsATest") {}
Foo::Foo(...) : Bar(CAMEL) {}
Foo::Foo(...) : Bar() {}
答案 2 :(得分:1)
这可能对您有用(GNU sed):
sed 's/\(Bar(\)"\([^"]\+\)"/\1\n\2\n/g;T;:a;s/_\n\n//g;ta;s/\n\([[:upper:]][[:lower:]]*\)/\U\1_\n/g;ta' file
在所有非空双引号字符串前后加上换行符,并以Bar(
开头。遍历上述字符串,在任何小写字母后插入下划线,然后将字符串大写(删除最后一个下划线和引入的换行符)。