我只需要一点帮助,因为我很少接触sed或awk。我正在尝试替换
String1.append("Hello"); // regexp to find this is: \w*\.append\(".*"\)
与
String1.append("Hello", 5); // note it has to figure out the length of "Hello"
我需要进行搜索并替换成千上万的文件。并且“Hello可以是任何东西......包括”\ n \ n \ n“,它应该是3而不是6.例如:
s.append("\n\n\n"); ---> s.append("\n\n\n", 3);
提前感谢您提供任何帮助......我想我需要awk这样做,所以我现在正在阅读有关awk基础知识的教程...
答案 0 :(得分:5)
由于您希望在包含代码的某些文件上运行此功能,因此以下是该完整功能的示例:
$ cat file
foo() {
String1.append("Hello");
if (bar) {
s.append("\n\n\n");
}
else {
s.append("\n\\n\n\\\n");
}
}
$
$ cat tst.awk
match($0,/[[:alnum:]_]+\.append\(".*"\)/) {
split(substr($0,RSTART,RLENGTH), orig, /"/)
head = substr($0,1,RSTART-1) orig[1]
tail = orig[3] substr($0,RSTART+RLENGTH)
tgt = orig[2]
gsub(/[\\][\\]/,"X",tgt)
gsub(/[\\]/,"",tgt)
$0 = sprintf("%s\"%s\", %d%s", head, orig[2], length(tgt), tail)
}
{ print }
$
$ awk -f tst.awk file
foo() {
String1.append("Hello", 5);
if (bar) {
s.append("\n\n\n", 3);
}
else {
s.append("\n\\n\n\\\n", 6);
}
}
我将原始发布问题中的示例中的“\ w”替换为POSIX等效“[[:alnum:] _]”以便于移植。 “\ w”将与GNU awk和其他一些工具一起使用,但不是所有工具,也不是所有工具。
答案 1 :(得分:3)
由于这是C ++,您是否考虑过使用预处理器?另外,您可以考虑使用sizeof
运算符,而不是自己计算每个字符串的长度。
#define append(x) appendSize(x, sizeof(x))
当然,这假设传递给append
的“x”总是一个字符串文字(但是,如果它不是那么没有找到并且替换脚本也将起作用)。
答案 2 :(得分:2)
这可能更适合作为评论,但更难以显示信息。在我看来,尝试通过修改源来优化字符串长度可能不是最好的解决方案。也许有一个很好的理由,但将它留给编译器可能是一个更好的解决方案(并且更简单)。根据编译器和选项,甚至可能不使用strlen()调用。编译器可以计算出常量字符串的长度。例如,考虑一下:
int main(int argc, char** argv)
{
string s = argv[1];
cout << s << endl;
s.append( " stuff" );
cout << s << endl;
return 0;
}
使用-O(g++ -O file.c
)编译时,汇编的相关位是:
400ad2: ba 06 00 00 00 mov $0x6,%edx
400ad7: be 6c 0c 40 00 mov $0x400c6c,%esi
400adc: 48 89 e7 mov %rsp,%rdi
400adf: e8 0c fe ff ff callq 4008f0 <_ZNSs6appendEPKcm@plt>
注意第一条mov
指令。已经计算出长度为6的长度。
将-O2
与Microsoft编译器(v16.00.40219.01)一起使用会产生类似的内容:
0000005C: 6A 06 push 6
0000005E: 68 00 00 00 00 push offset ??_C@_06PNGALGA@?5stuff?$AA@
00000063: 8D 4C 24 0C lea ecx,[esp+0Ch]
00000067: E8 00 00 00 00 call ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z
答案 3 :(得分:-1)
请有人改进这个解决方案:
x='String1.append("Hello");'
len=`echo $x | sed 's/\\//g' | sed 's/\w*\.append("\(.*\)");/\1/' | awk '{print length($0)}'`
echo $x | sed "s/\(\w*\.append(\".*\"\)\(.*\)/\1,$len\2/"
这似乎解决了原来的问题,但是多行。
答案 4 :(得分:-1)
是的perl!
x='String1.append("Hello");'
echo $x | perl -pe 's/(\w*\.append\(\")(.*)(\"\);)/my($len)=length($2); $_="$1$2, ${len}$3";/e'