如何修改 sql 文件中的特定行?
How to modify specific line in sql file?
我正在尝试修改目录中 sql 文件中的一行。
目前已经编写了根据用户输入导航到文件目录的代码。
该目录中的每个 sql 文件都有这两行:
--liquibase formatted sql
--changeset Jack:1 runOnChange:true splitStatements:false stripComments:false
我想做的是遍历所有文件,我想在每次脚本运行时更改设置。
所以这两行看起来像这样:
--liquibase formatted sql
--changeset Ryan:2 runOnChange:true splitStatements:false stripComments:false
我想在行中更改的部分是不变的,但是每个文件的内容都不同,就像在其他文件中一样Jie:6
我想用Priyal:7
替换它。所以名称部分是 运行 脚本的人,并且 : 之后的数字递增
是否有更简洁的方法来实现此目的:
这只是我配置路径和所有内容的示例代码:
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"
我将使用os.walk
遍历path_to_dest
中的所有文件
您可以使用正则表达式来解决这个问题:
如果找到正确的序列并保留该行的其余部分,以下代码会将字符串 "name1:1" 替换为 "name2:2":
import re
# read the file, line by line and then:
line_fixed = re.sub(r"(--changeset )name1:1(.*)", r"name2:2", line)
# then save the fixed line to a temporary file until you read all file
如果您的文件名为 "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
不是常量,那么我们仍然可以在“:”处拆分标记以识别“:”之后的数字,但要识别以我们必须使用的名称结尾的数字正则表达式。
这是一种使用正则表达式的方法:
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'
我正在尝试修改目录中 sql 文件中的一行。 目前已经编写了根据用户输入导航到文件目录的代码。
该目录中的每个 sql 文件都有这两行:
--liquibase formatted sql
--changeset Jack:1 runOnChange:true splitStatements:false stripComments:false
我想做的是遍历所有文件,我想在每次脚本运行时更改设置。
所以这两行看起来像这样:
--liquibase formatted sql
--changeset Ryan:2 runOnChange:true splitStatements:false stripComments:false
我想在行中更改的部分是不变的,但是每个文件的内容都不同,就像在其他文件中一样Jie:6
我想用Priyal:7
替换它。所以名称部分是 运行 脚本的人,并且 : 之后的数字递增
是否有更简洁的方法来实现此目的:
这只是我配置路径和所有内容的示例代码:
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"
我将使用os.walk
path_to_dest
中的所有文件
您可以使用正则表达式来解决这个问题: 如果找到正确的序列并保留该行的其余部分,以下代码会将字符串 "name1:1" 替换为 "name2:2":
import re
# read the file, line by line and then:
line_fixed = re.sub(r"(--changeset )name1:1(.*)", r"name2:2", line)
# then save the fixed line to a temporary file until you read all file
如果您的文件名为 "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
不是常量,那么我们仍然可以在“:”处拆分标记以识别“:”之后的数字,但要识别以我们必须使用的名称结尾的数字正则表达式。
这是一种使用正则表达式的方法:
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'