用于更改C++类名的脚本

Tho*_*ews 6 c++ bash perl cygwin sed

我已将类从全局命名空间移动到特定命名空间.我也改变了班级名称.我想将使用这些类的所有源文件转换为新格式.我正在考虑bash使用sedCygwin上的文件或执行perl脚本的脚本.我在bash剧本上遇到了麻烦.

这是我正在尝试执行的过程:

  1. 对于每个源文件,*.cpp和*.hpp,递归:
  2. 如果文件包含旧类名,则转换该文件.
  3. 结束.

我在Bash脚本中的问题是检测文件是否包含旧的类名.我在想grep每个类名的一个陈述:

for f in `find . -iname \*.[ch]pp`;
do
  if [ grep "Field_Blob_Medium" $f -eq 0 || grep "Field_Boolean" ]; then
      sed -f conversion.sed $f
  fi
done
Run Code Online (Sandbox Code Playgroud)

问题是Bashif语句中只有一个命令可以使用以下语法:

if grep "Field_Unsigned_Short" $f;
Run Code Online (Sandbox Code Playgroud)

所以我不能对greps 进行逻辑运算.

我可以执行嵌套循环,但我不知道如何break摆脱Bashfor循环:

OLD_CLASS_NAMES="Field_Blob_Medium Field_Boolean Field_Unsigned_Int"
for f in `find . -iname \*.[ch]pp`;
do
  for c_name in $OLD_CLASS_NAMES;
  do
     if grep $c_name $f then
        sed -f convert.sed $f # <-- Need to break out of inner loop after this execution.
     fi
  done
done
Run Code Online (Sandbox Code Playgroud)

所以我正在寻找有关如何处理包含旧类名的每个源文件并将其转换为新类的建议.Bash尽管Perl脚本也是可以接受的,但首选Cygwin 脚本示例. 此外,脚本应在将转换后的内容写入文件之前制作原始源文件的备份副本new.

我在Windows XP和Windows Vista上运行Cygwin.

Gre*_*con 2

不要回避 Perl:它使此类任务变得简单!

#! /usr/bin/perl -i.bak

use warnings;
use strict;

my $old = join "|" => qw(
  Field_Blob_Medium
  Field_Boolean
  Field_Unsigned_Int
);

chomp(@ARGV = `find . -iname \*.[ch]pp -print0 |
               xargs -0 grep -lE '($old)'`);

unless (@ARGV) {
  warn "$0: nothing to do!\n";
  exit 0;
}

while (<>) {
  s[Field_Blob_Medium]  [my::ns::MediumBlob]g ||
  s[Field_Boolean]      [my::ns::Bool]g       ||
  s[Field_Unsigned_Int] [my::ns::UInt]g;

  print;
}
Run Code Online (Sandbox Code Playgroud)

-i开关用于就地编辑。它会自动创建备份并将转换后的结果写入原始位置。

设置@ARGV使得您好像只使用包含旧类名的文件*.cpp和文件来调用程序。*.hpp切换-Egrep启用扩展正则表达式,因此未转义的()|是元字符。

如果没有命中(,if@ARGV为空),则无需执行任何操作。

否则,对于每个文件中具有旧名称的每一行(Perl 为您处理的机制!),尝试重命名Field_Blob_Mediummy::ns::MediumBlob等等。请注意,这些替换尝试在第一次成功后就会停止,因此如果一行包含两个不同的旧名称,一个将被替换,另一个将保持不变。

通常替换运算符写作s///,但您可以使用上面的括号分隔符。我这样做是为了使新名称左对齐。

当然,这是您实际替换的替代品。

最后,print可能修改的行,因为-i它会将其写入更新的源文件。