Привет, камрады!Есть питоновские файлы 200 штук. Нужно в конкретном классе поменять "return self.name" на "return self.displayname". Проблема в том, что "return self.name" около 10-15шт, а нужна конкретная. Помогите.
Руками не кошерно.
> Привет, камрады!
> Есть питоновский файлы 200 штук. Нужно в конкретном классе поменять "return self.name"
> на "return self.displayname". Проблема в том, что "return self.name" около
> 10-15шт, а нужна конкретная. Помогите.
> Руками не кошерно.ну так конкретная должна быть привязана к какой-то конкретной строке, до или после
внимание вопрос - к какой?имя сестра, имя! (с) ☺
>> Привет, камрады!
>> Есть питоновский файлы 200 штук. Нужно в конкретном классе поменять "return self.name"
>> на "return self.displayname". Проблема в том, что "return self.name" около
>> 10-15шт, а нужна конкретная. Помогите.
>> Руками не кошерно.
> ну так конкретная должна быть привязана к какой-то конкретной строке, до или
> после
> внимание вопрос - к какой?
> имя сестра, имя! (с) ☺Согласен, плохо объяснил.
class Meta:
db_table = u'type' - уникальная строкаdef __unicode__(self):
return self.name - нужно поменять
что-то вроде этого (где "type" - уникальная строка):grep -R -l type . | xargs sed -i 's/self.name/self.displayname/g'
> что-то вроде этого (где "type" - уникальная строка):
> grep -R -l type . | xargs sed -i 's/self.name/self.displayname/g'Твоя строка находит все файлы в которых есть уникальная строка (допустим это правильно), но потом она меняет ВСЕ "self.name" в файле на "self.displayname". А мне же нужно поменять "self.name" только рядом с уникальной строкой.
Файлов много, уникальная строка не везде на одном номере строки.
Можно и руками, но мне же хочется решить задачу автоматизированно. На С вопрос решиться сравнением строк, а вот на Bash я не умею, но что-то подсказывает это проще чем мне кажется.Можно ли на bash найти уникальную строчку и после нее сделать первую и единственную замену "self.name" на "self.displayname"?
> Есть питоновские файлы 200 штук. Нужно в конкретном классе поменять "return self.name"
> на "return self.displayname". Проблема в том, что "return self.name" около
> 10-15шт, а нужна конкретная. Помогите.
> Руками не кошерно.№1 - сэкономит ли программа больше времени, чем ушло на её написание? Если нет, зачем её писать?
№2 - на Perl это делается так:
perl -pe 's/return self.name/return self.displayname/g if /^class Meta/ .. /^class (?!Meta)/;' filename.pyОграничение - class Meta должен быть не последним в файле filename.py.
>[оверквотинг удален]
>> 10-15шт, а нужна конкретная. Помогите.
>> Руками не кошерно.
> №1 - сэкономит ли программа больше времени, чем ушло на её написание?
> Если нет, зачем её писать?
> №2 - на Perl это делается так:
>
> perl -pe 's/return self.name/return self.displayname/g if /^class Meta/ .. /^class (?!Meta)/;'
> filename.py
>
> Ограничение - class Meta должен быть не последним в файле filename.py.№1 - поэтому и прошу помощи
№2 - что-то не отработало. Попробую пошаманить.
> №2 - что-то не отработало. Попробую пошаманить.Оно не меняет сам файл, оно вываливает в stdout новое содержимое. Что с ним делать - вопрос второй (т.е. перехватывай stdout и складывай куда хочешь).
Например:
mkdir src.new
find src.old -name '*py' | while read srcname
do
perl -pe 's/return self.name/return self.displayname/g if /^class Meta/ .. /^class (?!Meta)/;' $srcname > src.new/$(basename $srcname)
doneС подкаталогами тоже нужно что-то делать. См.№1
>[оверквотинг удален]
> с ним делать - вопрос второй (т.е. перехватывай stdout и складывай
> куда хочешь).
> Например:
> mkdir src.new
> find src.old -name '*py' | while read srcname
> do
> perl -pe 's/return self.name/return self.displayname/g if /^class Meta/ ..
> /^class (?!Meta)/;' $srcname > src.new/$(basename $srcname)
> done
> С подкаталогами тоже нужно что-то делать. См.№1Спасибо! Написал на С. ))
>[оверквотинг удален]
>> куда хочешь).
>> Например:
>> mkdir src.new
>> find src.old -name '*py' | while read srcname
>> do
>> perl -pe 's/return self.name/return self.displayname/g if /^class Meta/ ..
>> /^class (?!Meta)/;' $srcname > src.new/$(basename $srcname)
>> done
>> С подкаталогами тоже нужно что-то делать. См.№1
> Спасибо! Написал на С. ))ну ты конкретно кросавчег, просто какой-то монстр ))
> Спасибо! Написал на С. ))Иногда усердие превозмогает разум. (с)
> что-то не отработалои у меня,
но идея поданапопробуем так, прямолинейно
#!/usr/bin/perl$file = shift;
open FH, $file;
$pat1 = 'db_table = u\'type\'';
while (<FH>) {
next unless /$pat1/;
next unless $_ = <FH> and $_ =~ /^$/;
next unless $_ = <FH> and $_ =~ /\S+/;
next unless $_ = <FH> and $_ =~ /self\.name/;
# если после изменяемой строки нет пустой строки, то следующую строку закоментить
next unless $_ = <FH> and $_ =~ /^$/;
next unless $_ = <FH>;
$pat2 = $_;
}close FH;
open FH, $file;
while (<FH>) {
s/self\.name/self\.displayname/ if /$pat1/ .. /$pat2/;
print;
}close FH;
использовать так
./script.pl /in/file.old > /out/file.new
>> что-то не отработало
> и у меня,
> но идея подана[...]
Улучшения улучшений не следует петь и танцевать.
> # если после изменяемой строки нет пустой строки,
> то следующую строку закоментитьЭто не гарантируется. Мало того, там может быть две пустых строки.
> $pat2 = $_;
Теперь представь, что у тебя попалась такая конструкция
x = x +1
self.name .= x
y = y -2
self.name .= y
return self.name> close FH;
> open FH, $file;В приличных местах это делается с помощью seek.
> Улучшения улучшений не следует петь и танцевать.ладно! построю свой лунапарк
#!/usr/bin/perlс блэкджеком и шлюxaми ))while (<>) {
print;
next unless /db_table = u'type'/;
next unless $_ = <> and /^$/;
print;
next unless $_ = <> and /\w+/;
print;
next unless $_ = <>;
s/name/displayname/;
print;
}
continue to build Luna Park ))сразу хочу заметить, что всё дальнейшее уже для ТС не актуально, он уже решение для себя на Сях написал
но вдруг кому пригодится, хотя у меня конечно есть сильное подозрение, что это такой секрет Полишинеля ))итак, есть какой-либо текст и в нём нужно заменить/удалить какой-либо фрагмент текста или слово
причём этот фрагмент текста или слово повторяется в тексте неоднократно
но удаление/замену нужно выполнить после определённого текста/слова в данном текстенапример в следующем тексте нужно заменить слово cat на слово DOG
но заменить нужно первое вхождение после определённого текста,
в данном случае пусть это будет слово replace
it is a simple text containing the word cat and other words
the word cat is found in this text several timesthis text is divided into several paragraphs
this is the word cat and the word cat yetneed to replace the word cat with the word DOG
but you need to replace the first occurrence of the word cat after the word "replace"please do not touch the other cats
the other words in the text of the cat does not replace
the rest of the text remains unchangedдля того чтобы прочесть текст одним куском установим разделитель в неопределённое значение
#!/usr/bin/perllocal $/ = undef;
$file = <>;
$file =~ s/(replace(?:(?!cat)).*?)cat/$1DOG/s;
print $file;ну и разумеется, однострочник, куда же без него ))
нужно использовать ключик -0777 чтобы заставить читать весь файл сразу одним куском
ну и знак "!" в FreeBSD необходимо экранироватьполучится
perl -0777 -pe 's/(replace(?:(?\!\cat)).*?)cat/$1DOG/s' text
а так можно заменить/удалить просто первое вхождение котаperl -0777 -pe 's/((?:(?\!\cat)).*?)cat/$1DOG/s' textвозвращаясь к первоначальной задаче топикстартера всё это приобретает следующий вид
#!/usr/bin/perllocal $/ = undef;
$file = <>;
$file =~ s/(db_table\s=\su'type'(?:(?!self\.name)).*?)self\.name/$1self\.displayname/s;
print $file;и это всё без регистрации и смс, безо всяких там условностей и ограничений ))
в однострочном варианте выглядит не так красиво и изящно как хотелось бы, вылезают косяки с одинарными кавычками
решение подсмотрел здесь же на opennet'е ==> http://www.opennet.dev/tips/info/2393.shtml
env re="'" perl -0777 -pe 's/(db_table = u$ENV{re}type$ENV{re}(?:(?\!self\.name)).*?)self\.name/$1self\.displayname/s' txtиспользование -i.bak заставит perl переписать исходный текст и скопировать исходный вариант в файл txt.bak
env re="'" perl -i.bak -0777 -pe 's/(db_table = u$ENV{re}type$ENV{re}(?:(?\!self\.name)).*?)self\.name/$1self\.displayname/s' txtповторю - это уже неважно, но всё же, вдруг пригодится кому-то ещё
такие дела
Почему не важно? Я вот прочитал и для себя сделал пометочку.
Спасибо.