Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 else 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.

like image 957
helpermethod Avatar asked Feb 04 '26 09:02

helpermethod


1 Answers

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,
like image 164
Shawn Chin Avatar answered Feb 05 '26 21:02

Shawn Chin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!