2011-08-31 44 views
1

我想遞歸遍歷目錄,發現有下列一組函數調用的至少一個所有文件:遞歸遍歷目錄,替換函數調用

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(...)。 希望有任何幫助!提前致謝!

+0

爲什麼你需要同時標記python和perl?如果你在linux平臺上工作,sed和grep應該綽綽有餘 – ajreal

+1

@ajreal,那我就不會看到它了。 – ikegami

回答

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) 
-2

你可能想看看使用awk。我並不是說sed不能這樣做,但它可能會變得更清潔,更具管理性。

Awk Tutorial

+0

因爲你沒有在這裏提供解決方案,所以你得到了低調,它更像是一個建議。在這種情況下,你應該發表評論而不是答案。 – Lynch

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"; 
    } 
' {} + 

使得很多的假設。如果其中一人產生太多問題,請告訴我。

+0

雖然這樣你不能對你改變的文件進行備份。 – TLP

+0

@TLP,我的意思是使用'-i.bak',它做備份。固定。請注意,我的代碼比unutbu的代碼更少假設。 – ikegami

+0

這也是我的想法,但是你複製了所有的文件,而不僅僅是你改變的文件。不知道用'-i'選項可以做什麼。 – TLP