Python使用fileinput双循环修改文件时数据丢失问题咨询
问题:使用fileinput嵌套循环修改文件导致数据丢失
需求:在文件中特定关键词后添加数据库中的多行内容。但使用以下两种嵌套循环的fileinput修改结构时,均出现文件所有数据丢失的情况,附上代码片段,咨询问题原因及解决方法:
第一种代码结构
cur = mysqlcon.cursor() sql_select_query = """select name,AES_DECRYPT(passwd, 'hardpass') as passwd from fullusers WHERE id = %s""" # set variable in query cur.execute(sql_select_query, (iduser,)) myresult = cur.fetchone() nameuser = myresult['name'] passuser = myresult['passwd'] psuser = str(passuser,'utf-8') if mysqlcon: print ("Connected Successfully") else: print ("Connection Not Established") query = """select * from v_ips WHERE uid = %s""" cur.execute(query, (iduser,)) data = cur.fetchall() file_name = '/usr/local/etc/3proxy.cfg' for line in fileinput.FileInput(file_name,inplace=1): if 'allow login,'+ nameuser +'' in line: for x in data: line = line.rstrip() line = line.replace(line, line+'\rproxy -n -a -p8989 -i'+ x['ip'] +' -e'+ x['ip'] +'')
第二种代码结构
for line in fileinput.FileInput(file_name,inplace=1): if 'allow login,'+ nameuser +'' in line: line = line.rstrip() for x in data: line = line.replace(line, line+'\rproxy -n -a -p8989 -i'+ x['ip'] +' -e'+ x['ip'] +'')
问题原因
- inplace模式核心要求未满足:使用
inplace=1时,fileinput会将标准输出重定向到原文件,必须在循环中打印每一行内容,否则原文件会被清空。你的代码既没有打印未匹配的行,也没有正确输出修改后的匹配行,导致文件内容全部丢失。 - 嵌套循环逻辑错误:循环数据库数据时,反复修改同一个
line变量,但最终没有将所有生成的内容打印出来,甚至连原行都没输出,相当于没有向文件写入任何有效内容。
解决方法
修正代码逻辑,确保所有行都被输出,同时正确处理匹配行后的多行添加:
cur = mysqlcon.cursor() sql_select_query = """select name,AES_DECRYPT(passwd, 'hardpass') as passwd from fullusers WHERE id = %s""" cur.execute(sql_select_query, (iduser,)) myresult = cur.fetchone() nameuser = myresult['name'] passuser = myresult['passwd'] psuser = str(passuser,'utf-8') if mysqlcon: print("Connected Successfully") else: print("Connection Not Established") query = """select * from v_ips WHERE uid = %s""" cur.execute(query, (iduser,)) data = cur.fetchall() file_name = '/usr/local/etc/3proxy.cfg' # 修正后的代码 for line in fileinput.FileInput(file_name, inplace=1): # 先去除换行符,避免输出重复换行 line = line.rstrip('\n') # 匹配目标行 if f'allow login,{nameuser}' in line: # 先打印原匹配行 print(line) # 遍历数据库数据,逐行打印要添加的代理配置 for x in data: print(f'proxy -n -a -p8989 -i{x["ip"]} -e{x["ip"]}') else: # 打印未匹配的原行,保留原有内容 print(line)
修正要点
- 确保循环内每一行都被打印,不管是否匹配关键词,避免文件被清空。
- 匹配到目标行时,先输出原行,再逐行输出数据库中取出的内容,实现"在关键词后添加多行"的需求。
- 使用f-string简化字符串拼接,避免语法混乱和错误。
内容的提问来源于stack exchange,提问作者Андрей
相关产品推荐
相关产品推荐

