递归遍历目录并替换函数调用
我想要递归地遍历一个文件夹,找到所有至少包含以下函数调用之一的文件:
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(...)里。希望能得到一些帮助!提前谢谢!
2 个回答
1
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";
}
' {} +
这个代码做了很多假设。如果其中某个假设带来了太多问题,请告诉我。
1
这个代码使用了 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)