Строки замены в файлах Python

Я не попробовал его, и это - чрезвычайный пожиратель ресурсов, но возможно выполняющий итерации с .fetch() и определяющий, что смещение работало бы?

LIMIT=1000
def count(query):
   result = offset = 0
   gql_query = db.GqlQuery(query)
   while True:
     count = gql_query.fetch(LIMIT, offset)
     if count < LIMIT:
       return result
     result += count
     offset += LIMIT
13
задан Alan Moore 15 January 2010 в 17:27
поделиться

3 ответа

Поместите весь этот код в файл с именем mass_replace . В Linux или Mac OS X вы можете выполнить chmod + x mass_replace , а затем просто запустить это. В Windows вы можете запустить его с помощью python mass_replace с соответствующими аргументами.

#!/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>\n"
    sys.stderr.write(u)
    sys.exit(1)

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

РЕДАКТИРОВАТЬ: Я изменил приведенный выше код из исходного ответа. Есть несколько изменений. Во-первых, mass_replace () теперь вызывает re.compile () для предварительной компиляции шаблона поиска; во-вторых, чтобы проверить, какое расширение имеет файл, теперь мы передаем кортеж расширений файла в .endswith () , а не вызываем .endswith () три раза; в-третьих, теперь он использует оператор with , доступный в последних версиях Python; и наконец, file_replace () теперь проверяет, найден ли шаблон в файле, и не перезаписывает файл, если шаблон не найден. (Старая версия перезаписывала каждый файл, изменяя временные метки, даже если выходной файл был идентичен входному файлу; это было неэлегантно.)

РЕДАКТИРОВАТЬ: Я изменил это значение по умолчанию на замену каждого файла, но с одной строкой вы можете изменить, чтобы ограничить его определенными расширениями. Я думаю, что замена каждого файла по умолчанию более полезна. Это можно было бы дополнить списком расширений или имен файлов, которые нельзя трогать, опциями, чтобы сделать регистр нечувствительным и т.д.

РЕДАКТИРОВАТЬ: В комментарии @asciimo указал на ошибку. Я отредактировал это, чтобы исправить ошибку. str.endswith () задокументировано для приема кортежа строк, но не списка. Исправлена. Также, Я заставил несколько функций принимать необязательный аргумент, позволяющий передавать кортеж расширений; это должно быть довольно легко изменить, чтобы принять аргумент командной строки, чтобы указать, какие расширения.

23
ответ дан 1 December 2019 в 19:02
поделиться

Вам действительно нужны регулярные выражения?

import os

def recursive_replace( root, pattern, replace )
    for dir, subdirs, names in os.walk( root ):
        for name in names:
            path = os.path.join( dir, name )
            text = open( path ).read()
            if pattern in text:
                open( path, 'w' ).write( text.replace( pattern, replace ) )
9
ответ дан 1 December 2019 в 19:02
поделиться

Of course, if you just want to get it done without coding it up, use find and xargs:

find /home/noa/Desktop/codes -type f -print0 | \
xargs -0 sed --in-place "s/dbname=noa user=noa/dbname=masi user=masi"

(And you could likely do this with find's -exec or something as well, but I prefer xargs.)

3
ответ дан 1 December 2019 в 19:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: