要专门解决您的实际错误,您需要在代码中(奇怪地)使用子流程模块时导入它:
import subprocess
之后,你会发现更多的问题。我会尽量让我的建议尽可能简单。先写代码,然后我会分解它。请记住,有更强大的方法可以完成此任务。但我正在尽我所能记住您的经验水平,并使其尽可能接近您当前的方法。
import subprocess
import sys
# 1
results = subprocess.Popen("find . -name '*.tml'",
shell=True, stdout=subprocess.PIPE)
if results.wait() != 0:
print "error trying to find tml files"
sys.exit(1)
# 2
tml_files = []
for tml in results.stdout:
tml_files.append(tml.strip())
if not tml_files:
print "no tml files found"
sys.exit(0)
tml_string = " ".join(tml_files)
# 3
with open ("file1.txt") as f, open("file2.txt") as g:
while True:
# 4
f_line = f.readline()
if not f_line:
break
g_line = g.readline()
if not g_line:
break
f_line = f_line.strip()
g_line = g_line.strip()
if not f_line or not g_line:
continue
# 5
cmd = "sed -i -e 's/%s/%s/g' %s" % \
(f_line.strip(), g_line.strip(), tml_string)
ret = subprocess.Popen(cmd, shell=True).wait()
if ret != 0:
print "error doing string replacement"
sys.exit(1)
您不需要一次读入整个文件。如果它们很大,这可能是很多内存。您可以一次使用一行,还可以在打开文件时使用所谓的“上下文管理器”。无论发生什么,这将确保它们正确关闭:
我们从只运行一次以查找所有.tml
文件的子进程命令开始。您的版本多次运行相同的命令。如果搜索路径相同,那么我们只需要一次。这将检查命令的退出代码,如果失败则退出。
我们stdout
在 subprocess 命令上循环,并将剥离的行添加到列表中。这是您的一种更健壮的方式replace("\r\n")
。它删除空格。“列表理解”会更适合这里(下线)。如果我们没有找到任何 tml 文件,那么我们没有工作要做,所以我们退出。否则,我们将它们连接在一个空格分隔的字符串中,以便稍后适合我们的命令。
这称为“上下文管理器”。您可以以某种方式打开文件,无论它们是什么都将正确关闭。该文件在该代码块内的上下文长度内打开。我们将永远循环,并在适当的时候中断。
我们从每个文件中一次提取一行。如果任一行是空白的,我们就到了文件的末尾,不能再做任何工作,所以我们中断了。然后我们去掉换行符,如果任何一个字符串为空(空行),我们仍然不能做任何工作,但我们只是继续下一个可用的行。
sed 命令的修改版本。我们在每个循环上为源字符串和替换字符串构造命令字符串,并附加 tml 文件字符串。请记住,这是一种非常幼稚的替换方法。它确实希望您的替换字符串是安全字符,并且不会破坏s///g
sed 格式。但是我们用另一个subprocess
命令运行它。wait()
只是等待返回码,我们检查它是否有错误。这种方法取代了你的os.system()
版本。
希望这可以帮助。最终,您可以改进它以进行更多检查和安全操作。