Как изменить конкретную строку в файле sql?

#python #os.walk

#python #os.walk

Вопрос:

Я пытаюсь изменить строку в файле sql в каталоге. В настоящее время написан код, который переходит в каталог files в соответствии с пользовательским вводом.

каждый файл sql в этом каталоге содержит эти 2 строки:

 --liquibase formatted sql
--changeset Jack:1 runOnChange:true splitStatements:false stripComments:false
  

Я пытаюсь выполнить цикл по всем файлам, и я хочу изменять настройки при каждом запуске скрипта.

итак, эти 2 строки будут выглядеть следующим образом :

  --liquibase formatted sql
 --changeset Ryan:2 runOnChange:true splitStatements:false stripComments:false
  

Часть, которую я хочу изменить в строке, является постоянной, но содержимое отличается для каждого файла, как и в другом файле, которым оно будет, Jie:6 я хочу заменить это на Priyal:7 . Таким образом, часть имени — это человек, который запускает скрипт, а число после: увеличивается

Есть ли более чистый способ добиться этого :

Это всего лишь пример кода, который у меня есть, который настраивает path и все остальное :

 anbpath = os.path.abspath("copy_views.py")
 print(anbpath)

sqldir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'database')) 

path_to_views = sqldir "/sql/edm/changes/" source_release_version "/mutable/view"
print(path_to_views)


destdir = os.path.abspath(os.path.join(os.path.dirname( __file__ ),'..', 'database')) 

path_to_dest_rel_ver = destdir "/sql/edm/changes/" dest_release_version

path_to_dest = path_to_dest_rel_ver "/mutable/view"
  

Я пройдусь по всем файлам в path_to_dest с помощью os.walk

Комментарии:

1. Пожалуйста, исправьте форматы, отступы кода и опечатки в вашем вопросе.

2. Надеюсь, теперь все выглядит хорошо @gdlmx

3. Правильно обновил формат

4. @PriyalChaudhari вы хотите name4:6 заменить на name5:7 , т.е. оставить имя как есть и увеличить оба числа?

5. @mujjiga Фактическое содержимое — Jack: 1 или Ryan: 4, например, это демо-имена, которые я использовал

Ответ №1:

Если ваш файл вызывается «file.txt «и если name является постоянным, то то, что вы ищете, это

 # Read the contents of file
with open("file.txt", 'r') as fp:
    lines = fp.readlines()

#Idendify tokens and numbers with in them and increment them
words = lines[1].split()
tokens = words[1].split(":")
words[1] = "name{0}:{1}".format(int(tokens[0][4:]) 1, int(tokens[1]) 1)
lines[1] = ' '.join(words)

# Write back the updated lines
with open("file.txt", 'w') as fp:
    fp.writelines(lines)
  

Исходное содержимое файла

"--liquibase formatted sql",
"--changeset name3:21 runOnChange:true splitStatements:false stripComments:false"]

Последующее изменение

"--liquibase formatted sql",
"--changeset name4:22 runOnChange:true splitStatements:false stripComments:false"]

Однако, если name не является константой, мы все равно можем разделить токен на «:», чтобы указать число после «:», но для определения числа, заканчивающегося на имени, нам придется использовать регулярное выражение.

Комментарии:

1. Спасибо, это помогает. Нет, после имени нет номера. Это просто демонстрационные имена, которые я использовал. Фактические имена похожи на Jack, Ryan so . Мне придется беспокоиться о числе после :

2. Мой файл имеет расширение .sql

3. Я думаю, что это решение создаст проблемы, поскольку файл также содержит код sql, эти 2 строки находятся в начале файла. Если я разделю на: это также разделит код sql. Я не хочу касаться этой части

4. @PriyalChaudhari Если вы посмотрите на код, я работаю только над второй строкой lines[1] , код не затрагивает и не изменяет другие строки. Итак, пока она находится во 2-й строке, она должна работать.

5. понял, я попробую это, спасибо. Просто не уверен в той части, как обрабатывать реальные имена.

Ответ №2:

Вы можете использовать регулярное выражение для решения этой проблемы: следующий код заменит строку «name1: 1» на «name2:2», если найдет правильную последовательность, и сохранит остальную часть строки:

 import re

# read the file, line by line and then:
line_fixed = re.sub(r"(--changeset )name1:1(.*)", r"1name2:22", line)
# then save the fixed line to a temporary file until you read all file
  

Комментарии:

1. ВЫШЕ я ИСПОЛЬЗОВАЛ ПРИМЕР. Это не всегда `name1: 1`, оно отличается в каждом файле, как в каком-то файле, которым это может быть name8:6

2. Я надеюсь, что вы можете использовать мой ответ в качестве «примера» и руководства для решения вашей проблемы. С уважением.

Ответ №3:

Вот способ сделать это с помощью регулярных выражений:

 import re

lines = [
    "--liquibase formatted sql",
    "--changeset Jack:2 runOnChange:true splitStatements:false stripComments:false",
    "--liquibase formatted sql",
    "--changeset Ryan:6 runOnChange:true splitStatements:false stripComments:false",
#   etc ...
]

def update_line(line):
    p = re.compile(r'--changeset (. ):(d ) runOnChange')
    matches = p.match(line)
    if not matches:
        return line
    else:
        replacement = '--changeset {}:{} runOnChange'.format(matches.group(1),
                                                             int(matches.group(2)) 1)
        return p.sub(replacement, line)

for line in lines:
    updated_line = update_line(line)
    print(repr(updated_line))
  

Вывод:

 '--liquibase formatted sql'
'--changeset Jack:3 runOnChange:true splitStatements:false stripComments:false'
'--liquibase formatted sql'
'--changeset Ryan:7 runOnChange:true splitStatements:false stripComments:false'