Я переместил свои классы от глобального пространства имен в определенное пространство имен. Я также изменил имена классов. Я хочу преобразовать все свои исходные файлы, которые используют эти классы для нового формата. Я думал любой a bash
сценарий с помощью a sed
файл на Cygwin или выполнении сценария жемчуга. Я испытываю затруднения из-за 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 grep "Field_Unsigned_Short" $f;
таким образом, я не могу сделать логического ИЛИ grep
s.
Я мог выполнить вложенный цикл, но я не знаю как к break
из a Bash
для цикла:
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
Таким образом, я ищу предложения о том, как обработать каждый исходный файл, который содержит старые имена классов, и преобразуйте их в новые. Cygwin Bash
пример сценария предпочтен, хотя сценарий Perl также был бы приемлем. Кроме того, сценарий должен сделать резервную копию файла первоисточника перед выписыванием преобразованного содержания к new
файл.
Я выполняю Cygwin на Windows XP и Windows Vista.
MyClass myObj();
Эта функция анализируется как объявление функции, называется myObj, не принимает аргументов и возвращает объект MyClass. Я никогда не видел, чтобы составитель принимал это. С другой стороны MyClass * myPtr = new MyClass ();
является приемлемым, может быть, вы запутались?
Я бы добавил все в одно слово. Если не сложить все вместе, я бы либо сократил его, либо использовал _
.
В долгосрочной перспективе все, что вы решите выбрать, должно быть непротиворечивым .
-121--4561275-Не уклоняйтесь от 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:: Medium Blob
и так далее. Обратите внимание, что эти попытки замены прекращаются после первого успеха, поэтому, если строка содержит два разных старых имени, одно будет заменено, а другое останется прежним.
Обычно оператор подстановки записывается s///
, но можно использовать квадратные разделители, как описано выше. Я сделал это, чтобы оправдать новые имена.
Конечно, это резерв для вашей фактической замены.
Наконец, напечатайте
возможно измененную строку, которая из-за -i
записывает ее в обновленный исходный файл.
Это работает на моем 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
Вы можете использовать параметр регулярного выражения для grep, чтобы дать вам больше гибкости в поиске. В вашем примере:
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 ...
... на случай, если вы захотите упростить этот цикл.