2010-06-24 89 views
5

我想学习使用python作为命令行脚本替换。我过去花了一些时间用python,但这已经有一段时间了。这似乎在它的范围之内。通过python跨文件夹中的所有文件进行搜索和替换?

我在一个文件夹中有几个文件,我想在它们的内部进行搜索和替换。我想用python脚本来做。

例如,搜索并将“foo”的所有实例替换为“foobar”。

回答

2

一般情况下我马上拿出老perl -pi -e 's/foo/foobar/'这一点,但如果你想要的Python:

import os 
import re 
_replace_re = re.compile("foo") 
for dirpath, dirnames, filenames in os.walk("directory/"): 
    for file in filenames: 
     file = os.path.join(dirpath, file) 
     tempfile = file + ".temp" 
     with open(tempfile, "w") as target: 
      with open(file) as source: 
       for line in source: 
        line = _replace_re.sub("foobar", line) 
        target.write(line) 
     os.rename(tempfile, file) 

如果你使用的是Windows,你需要的os.rename(tempfile, file)前添加os.remove(file)

+0

另外,它可能是很好的把在一个小的检查,以验证'tempfile'不存在... – 2010-06-24 14:00:30

+0

这似乎是有道理的。创建临时文件的行为就是这样,如果权限不够,我们仍然可以执行该操作?在这种情况下,删除和重命名也不起作用,对吗? – fruit 2010-06-24 14:03:45

+0

tempfile确保我们不会太早覆盖真实文件,以免我们在大文件上占用大量内存(这样做的理由很简单:'data = open(file ).read(); data = _replace_re.sub(“foobar”,data); open(file,“w”)。write(data)',但会使用大量内存,并且如果计算机崩溃一半'write',你会丢失未写入的数据) – 2010-06-24 14:53:17

1

我通过它工作,这似乎工作,但任何可以指出的错误将是真棒。

import fileinput, sys, os 

def replaceAll(file, findexp, replaceexp): 
    for line in fileinput.input(file, inplace=1): 
     if findexp in line: 
      line = line.replace(findexp, replaceexp) 
     sys.stdout.write(line) 

if __name__ == '__main__': 
    files = os.listdir("c:/testing/") 
    for file in files: 
     newfile = os.path.join("C:/testing/", file) 
     replaceAll(newfile, "black", "white") 

对此的扩展将移动到文件夹内的文件夹。

+0

你可能想要做的是把它改为'replaceAll(file,“black”,“white”)' - 如果你有'somedir/blackdir/blackfile.txt“,那么你会得到'somedir/whitedir/whitefile.txt'。当然,除非你想要那样,在这种情况下,请保持它的样子。 – 2010-06-24 15:20:58

+0

这个函数为什么要重命名文件?它正在逐行搜索它.. – fruit 2010-06-24 16:42:21

5

欢迎来到StackOverflow。既然你想学习你自己(+1),我只是给你一些指点。

查看os.walk()获取所有文件。

然后迭代文件中的每一行(for line in currentfile:在这里派上用场)。

现在,你需要知道,如果你想要一个“笨”替换(查找/替换每个foo即使是在一个字的中间(比如foobar - 你想foofoobar结果)或智能更换?

对于前者,看str.replace(),对于后者,看re.sub(),弄清r'\bfoo\b'手段。

+0

很酷,谢谢!学习新功能(os.walk())总是很好。它是否也遍历子目录?我假设你的链接会告诉我。 – fruit 2010-06-24 14:01:38

+0

是的,它的确如此:) – 2010-06-24 14:02:57

0

这是一种选择,因为你必须呈现给你不同的Python的解决方案,最有用的工具(根据我的说法),在Unix/Windows中,GNU find命令和替换工具(如sed/awk)来搜索f iles(递归)并进行替换,像这样的简单命令可以做到这一点(语法来自内存,未经测试)。这表示,找到所有文本文件和改变,同时这个词在内容上“老”到“新”,用sed备份原始文件...

$ find /path -type f -iname "*.txt" -exec sed -i.bak 's/old/new/g' "{}" +; 
相关问题