如何替换文件夹中多个文件中的字符串?

时间:2012-11-28 05:51:13

标签: python-2.7

我试图读取两个文件并用文件夹中存在子目录的文件中的其他文件的内容替换一个文件的内容。 但它的tell子流程没有定义。  我是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;

1 个答案:

答案 0 :(得分: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,并将剥离的行添加到列表中。这是replace("\r\n")更强大的方式。它删除了空格。 “列表理解”在这里更适合(下线)。如果我们没有找到任何tml文件,那么我们没有工作要做,所以我们退出。否则,我们将它们以空格分隔的字符串连接在一起,以便稍后适合我们的命令。

  3. 这称为“上下文管理器”。您可以以不管它们将被正确关闭的方式打开文件。该文件在该代码块内的上下文长度内打开。我们将永远循环,并在适当时打破。

  4. 我们从每个文件中一次拉一行。如果任一行是空白的,我们到达文件的末尾并且不能再做任何工作了,所以我们分手了。然后我们剥离换行符,如果任一字符串为空(空行),我们仍然无法做任何工作,但我们只是继续使用下一行。

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

  6. 希望这会有所帮助。最终,您可以改进这一点,以进行更多检查和安全操作。

相关问题