Я хотел бы рекурсивно пересекать каталог и находить все файлы, имеющие хотя бы один из вызовов функций следующего набора:
A(a)
B(a,b)
C(a,b,c)
теперь, невзирая на аргументы, я могу получить список таких файлов с
grep -r -l '[A-C](' .
хотя я уверен, что могу как-то соответствовать аргументам. В этих файлах я хочу сделать следующее: во-первых, я хочу создать резервную копию, то есть сохранить исходный файл в filename.ext_bak или что-то в этом роде, тогда как в файле filename.ext я хочу заменить каждое появление вызова функции
X(a,...)
от
#ifdef LOL
X_new(f(a),...)
#else
X(a,...)
#endif
где X может быть A, B, C и заметить, что каждый аргумент в X_new завернут в функцию f (...). Поблагодарили бы за любую помощь! Заранее спасибо!
Это использует os.walk для рекурсивного перемещения всех файлов (начиная с текущего рабочего каталога).
Аргумент backup='_bak'
сообщает fileinput.input делать резервную копию каждого файла.
import os
import sys
import re
import fileinput
def sub_callback(match):
func,args=match.groups()
fargs=','.join('f({a})'.format(a=a) for a in args.split(','))
return ('''\
#if def LOL
{func}_new({fa})
#else
{func}({a})
#endif
'''.format(func=func,a=args,fa=fargs))
for root, dirs, files in os.walk('.'):
for line in fileinput.input(
(os.path.join(root,name) for name in files),
inplace=True,
backup='_bak'
):
line=re.sub(r'\b([A-C])\((.*?)\)',sub_callback,line)
sys.stdout.write(line)
find -type f -exec perl -i.bak -pe'
if (my ($orig, $pre, $func, $args, $post) =
/^((.*)\b(A|B|C)\((.*?)\)(.*?))\n/s
) {
$args = join ', ', map { "f($_)" } split /,\s*/, $args;
$_ = "#ifdef LOL\n";
$_ .= $pre${func}_new($args)$post\n";
$_ .= "#else\n";
$_ .= $orig\n";
$_ .= "#endif\n";
}
' {} +
Делает много предположений. Дайте мне знать, если один из них создает слишком много проблем.
-i.bak
, который делает резервные копии. Исправлена. Обратите внимание, что мой код делает меньше предположений, чем код unutbu.