我已将类从全局命名空间移动到特定命名空间。我也改变了班级名称。我想将使用这些类的所有源文件转换为新格式。我在思考使用Cygwin上的bash
文件的sed
脚本或执行perl脚本。我在使用bash
脚本时遇到了麻烦。
这是我正在尝试执行的过程:
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
问题是只有一个命令可以在Bash
if语句中,使用以下语法:
if grep "Field_Unsigned_Short" $f;
因此我无法对grep
s进行逻辑或。
我可以执行嵌套循环,但我不知道如何break
for Bash
for循环:
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
所以我正在寻找有关如何处理包含旧类名的每个源文件并将其转换为新类的建议。尽管Perl脚本也可以接受,但首选Cygwin Bash
脚本示例。 此外,在将转换后的内容写入new
文件之前,脚本应制作原始源文件的备份副本。
我在Windows XP和Windows Vista上运行Cygwin。
答案 0 :(得分: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;
}
-i
开关用于就地编辑。它会自动创建备份并将转换后的结果写入原始位置。
设置@ARGV
就好像你只用那些包含旧类名的*.cpp
和*.hpp
文件调用了程序。 -E
切换为grep
可启用扩展正则表达式,因此未转义的(
,)
和|
是元字符。
如果没有命中(即,如果@ARGV
为空),则无事可做。
否则,对于每个具有旧名称的文件的每一行(Perl为您处理的机制!),尝试将Field_Blob_Medium
重命名为my::ns::MediumBlob
,依此类推。请注意,这些替换尝试在第一次成功后停止,因此如果一行包含两个不同的旧名称,则一个将被替换,另一个将保持不变。
通常替换运算符是s///
,但您可以使用上面的包围分隔符。我这样做是为了给新名字辩护。
当然,这是您实际替换的替身。
最后,print
可能修改的行,由于-i
将其写入更新的源文件。
答案 1 :(得分:1)
这个工作在我的linux上。它管理其他人指出的各种事情:
#!/bin/bash
OLD_NAMES="(EField_Blob_Medium|Field_Boolean|Field_Unsigned_Int)"
find "$1" -name "*.hpp" -o -name "*.cpp" -print0 | \
xargs -0 --replace grep -E "${OLD_NAMES}" {} && sed -i.save -f convert.sed {}
重要的是:
希望它有所帮助, MY2C
答案 2 :(得分:0)
您可以使用grep的regex选项为您的搜索提供更大的灵活性。根据你的例子:
if [ grep "Field_Blob_Medium" $f -eq 0 || grep "Field_Boolean" ];
可能是
if [ grep -E "(Field_Blob_Medium|Field_Boolean)" ... ];
你可以将这些'|'串在心里。
另外,你可以将你的发现合并到你的greps
find . -name "*.hpp" or -name "*.cpp" | xargs grep -E ...
...如果你想在那里简化那个循环。