0

我正在尝试读取两个文件,并将一个文件的内容替换为文件夹中存在的文件中的另一个文件的内容,该文件夹也有子目录。但它的告诉子过程没有定义。我是python和shell脚本的新手,有人可以帮我吗?

import os
import sys
import os.path

f = open ( "file1.txt",'r')
g = open ( "file2.txt",'r')
text1=f.readlines()
text2=g.readlines()

i = 0;
for line in text1:
    l = line.replace("\r\n", "")
    t = text2[i].replace("\r\n", "")
    args = "find . -name *.tml"
    Path = subprocess.Popen( args , shell=True )
    os.system("  sed -r -i 's/" + l + "/" + t + "/g' " + Path)
    i = i + 1;
4

1 回答 1

0

要专门解决您的实际错误,您需要在代码中(奇怪地)使用子流程模块时导入它:

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)

您不需要一次读入整个文件。如果它们很大,这可能是很多内存。您可以一次使用一行,还可以在打开文件时使用所谓的“上下文管理器”。无论发生什么,这将确保它们正确关闭:

  1. 我们从只运行一次以查找所有.tml文件的子进程命令开始。您的版本多次运行相同的命令。如果搜索路径相同,那么我们只需要一次。这将检查命令的退出代码,如果失败则退出。

  2. 我们stdout在 subprocess 命令上循环,并将剥离的行添加到列表中。这是您的一种更健壮的方式replace("\r\n")。它删除空格。“列表理解”会更适合这里(下线)。如果我们没有找到任何 tml 文件,那么我们没有工作要做,所以我们退出。否则,我们将它们连接在一个空格分隔的字符串中,以便稍后适合我们的命令。

  3. 这称为“上下文管理器”。您可以以某种方式打开文件,无论它们是什么都将正确关闭。该文件在该代码块内的上下文长度内打开。我们将永远循环,并在适当的时候中断。

  4. 我们从每个文件中一次提取一行。如果任一行是空白的,我们就到了文件的末尾,不能再做任何工作,所以我们中断了。然后我们去掉换行符,如果任何一个字符串为空(空行),我们仍然不能做任何工作,但我们只是继续下一个可用的行。

  5. sed 命令的修改版本。我们在每个循环上为源字符串和替换字符串构造命令字符串,并附加 tml 文件字符串。请记住,这是一种非常幼稚的替换方法。它确实希望您的替换字符串是安全字符,并且不会破坏s///gsed 格式。但是我们用另一个subprocess命令运行它。wait()只是等待返回码,我们检查它是否有错误。这种方法取代了你的os.system()版本。

希望这可以帮助。最终,您可以改进它以进行更多检查和安全操作。

于 2012-11-28T06:19:44.143 回答