开发者

Iterating over multiple files and replacing a single line - why doesn't it work?

I'm trying to use the fileinput module to iterate over a bunch of files and replace a single line in them. This is how my code looks:

def main():
    for root, dirs, files in os.walk('target/generated-sources'):
        for line in fileinput.input([os.path.join(root, file) for file in files if file.endsWith('.java')], inplace=True):
            match = re.search(r'@Table\(name = "(.*)"\)', line)
            output = "".join(['@Table(name = "', PREFIX, match.group(1)[MAX_TABLENAME_LEN - len(PREFIX)], '")', '\n']) if match e开发者_如何学编程lse line
            print output,

The problem I face is that I get no error, and the script somehow seems to block. I'm using Python 2.5.2.


Your list comprehension is returning empty lists when a root does not contain .java files. When your script passes an empty list to fileinput.input(), it reverts to the default expecting input from stdin. Since there is nothing coming in from stdin, your script blocks.

Try this instead:

def main():
    for root, dirs, files in os.walk('target/generated-sources'):
        java_files = [os.path.join(root, file) for file in files if file.endsWith('.java')]
        if not java_files:  # go to next iteration if list is empty
            continue
        for line in fileinput.input(java_files, inplace=True):
            match = re.search(r'@Table\(name = "(.*)"\)', line)
            output = "".join(['@Table(name = "', PREFIX, match.group(1)[MAX_TABLENAME_LEN - len(PREFIX)], '")', '\n']) if match else line
            print output,

Alternatively, split up the logic of the file discovery. The following creates a generator which produces a list of files which you can then use as an input to fileinput.

import os, fnmatch, fileinput

def find_files(directory, pattern):
    "Generator that returns files  within direction with name matching pattern"
    for root, dirs, files in os.walk(directory):
        for basename in fnmatch.filter(files, pattern):
            filename = os.path.join(root, basename)
            yield filename

for line in fileinput.input(find_files("target/generated-sources", "*.java")):
    match = re.search(r'@Table\(name = "(.*)"\)', line)
    output = "".join(['@Table(name = "', PREFIX, match.group(1)[MAX_TABLENAME_LEN - len(PREFIX)], '")', '\n']) if match else line
    print output,


If you want to know where the interpreter blocks, you can send signal SIGINT to the process. At least on unix like operating systems.

kill -sigint PID

Try to add some print or logging- lines, to see where your code hangs. Maybe fileinput works well, and the app blocks after that.

Some time ago I wrote a tool to do search+replace in several files: http://www.thomas-guettler.de/scripts/reprec.py.txt

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜