遍历多个文件并替换单行 - 为什么不起作用?
我正在尝试使用 fileinput
模块来遍历一堆文件,并在这些文件中替换一行内容。我的代码是这样的:
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,
我遇到的问题是没有任何错误提示,但脚本似乎卡住了。我使用的是 Python 2.5.2 版本。
2 个回答
1
如果你想知道解释器在哪儿卡住了,可以给这个进程发送一个叫SIGINT的信号。至少在类Unix的操作系统上是这样。
kill -sigint PID
你可以尝试加一些打印或者日志的代码,看看你的程序在哪儿停住了。也许fileinput运行得很好,但之后程序就卡住了。
不久前我写了一个工具,可以在多个文件中进行搜索和替换:http://www.thomas-guettler.de/scripts/reprec.py.txt
4
你的列表推导式在某个文件夹里没有找到 .java
文件时,会返回空列表。当你的脚本把这个空列表传给 fileinput.input()
时,它会回到默认设置,期待从标准输入(stdin)接收数据。因为标准输入没有任何数据进来,所以你的脚本就卡住了。
你可以试试这个:
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,
另外,你可以把文件查找的逻辑分开。下面的代码会创建一个生成器,这个生成器会产生一个文件列表,你可以把这个列表用作 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,