用 Python 替换文件中的字符串 [英] Replace strings in files by Python

查看:25
本文介绍了用 Python 替换文件中的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在给定目录及其子目录中递归地将匹配替换为给定的替换?

import os
import re
from os.path import walk
for root, dirs, files in os.walk("/home/noa/Desktop/codes"):
        for name in dirs:
                re.search("dbname=noa user=noa", "dbname=masi user=masi")
                   // I am trying to replace here a given match in a file

推荐答案

将所有这些代码放入一个名为 mass_replace 的文件中.在 Linux 或 Mac OS X 下,你可以执行 chmod +x mass_replace 然后运行它.在 Windows 下,您可以使用 python mass_replace 后跟适当的参数来运行它.

Put all this code into a file called mass_replace. Under Linux or Mac OS X, you can do chmod +x mass_replace and then just run this. Under Windows, you can run it with python mass_replace followed by the appropriate arguments.

#!/usr/bin/python

import os
import re
import sys

# list of extensions to replace
DEFAULT_REPLACE_EXTENSIONS = None
# example: uncomment next line to only replace *.c, *.h, and/or *.txt
# DEFAULT_REPLACE_EXTENSIONS = (".c", ".h", ".txt")

def try_to_replace(fname, replace_extensions=DEFAULT_REPLACE_EXTENSIONS):
    if replace_extensions:
        return fname.lower().endswith(replace_extensions)
    return True


def file_replace(fname, pat, s_after):
    # first, see if the pattern is even in the file.
    with open(fname) as f:
        if not any(re.search(pat, line) for line in f):
            return # pattern does not occur in file so we are done.

    # pattern is in the file, so perform replace operation.
    with open(fname) as f:
        out_fname = fname + ".tmp"
        out = open(out_fname, "w")
        for line in f:
            out.write(re.sub(pat, s_after, line))
        out.close()
        os.rename(out_fname, fname)


def mass_replace(dir_name, s_before, s_after, replace_extensions=DEFAULT_REPLACE_EXTENSIONS):
    pat = re.compile(s_before)
    for dirpath, dirnames, filenames in os.walk(dir_name):
        for fname in filenames:
            if try_to_replace(fname, replace_extensions):
                fullname = os.path.join(dirpath, fname)
                file_replace(fullname, pat, s_after)

if len(sys.argv) != 4:
    u = "Usage: mass_replace <dir_name> <string_before> <string_after>
"
    sys.stderr.write(u)
    sys.exit(1)

mass_replace(sys.argv[1], sys.argv[2], sys.argv[3])

我已经从原始答案中更改了上述代码.有几个变化.首先,mass_replace() 现在调用 re.compile() 来预编译搜索模式;其次,为了检查文件的扩展名,我们现在将文件扩展名的元组传递给 .endswith() 而不是调用 .endswith() 三次;第三,它现在使用最新版本的 Python 中可用的 with 语句;最后,file_replace() 现在检查是否在文件中找到该模式,如果未找到该模式,则不会重写该文件.(旧版本会重写每个文件,即使输出文件与输入文件相同,也会更改时间戳;这是不雅的.)

I have changed the above code from the original answer. There are several changes. First, mass_replace() now calls re.compile() to pre-compile the search pattern; second, to check what extension the file has, we now pass in a tuple of file extensions to .endswith() rather than calling .endswith() three times; third, it now uses the with statement available in recent versions of Python; and finally, file_replace() now checks to see if the pattern is found within the file, and doesn't rewrite the file if the pattern is not found. (The old version would rewrite every file, changing the timestamps even if the output file was identical to the input file; this was inelegant.)

我将此更改为默认替换每个文件,但您可以编辑一行以将其限制为特定扩展名.我认为替换每个文件是一种更有用的开箱即用默认值.这可以使用不可触及的扩展名或文件名列表、使其不区分大小写的选项等进行扩展.

I changed this to default to replacing every file, but with one line you can edit to limit it to particular extensions. I think replacing every file is a more useful out-of-the-box default. This could be extended with a list of extensions or filenames not to touch, options to make it case insensitive, etc.

在评论中,@asciimo 指出了一个错误.我编辑了这个以修复错误.str.endswith() 被记录为接受要尝试的字符串元组,而不是列表.固定的.另外,我让几个函数接受一个可选参数,让你传入一个扩展元组;修改它以接受命令行参数来指定哪些扩展应该很容易.

In a comment, @asciimo pointed out a bug. I edited this to fix the bug. str.endswith() is documented to accept a tuple of strings to try, but not a list. Fixed. Also, I made a couple of the functions accept an optional argument to let you pass in a tuple of extensions; it should be pretty easy to modify this to accept a command-line argument to specify which extensions.

这篇关于用 Python 替换文件中的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆