从 txt 中读取行。文件并在另一个文件上写入除前 6 行以外的所有内容,然后刷新第一个文件

Read lines from a txt. file and write all except 6 first lines on another, then flush the first file

我正在尝试创建一个 Python 代码来从电子邮件中读取数据,并将其保存到一个临时的 txt 文件中。文件。将有另一个永久性的 txt。文件,其中临时 txt。文件内容将以跳过前 6 行的形式写入。在此循环期间,临时文件被刷新,因此不会多次写入相同的数据。

这是我使用过的代码:

for part in email_message.walk():
    if part.get_content_type() == 'text/plain':
        body = part.get_payload(decode=True)
        save_string = str('C:/Email/file.txt')
        myfile = open(save_string, 'a')
        myfile.write(str(body)) ## Write to file 2 and then flush this 
        open ('C:/Email/file.txt','w+') as f:
        lines = f.readlines()
        open ('C:/Email/newfile.txt','a') as g:
        g.writelines(lines[6:])
        f.close()
        g.close()
        myfile.close()# Clear first file 
    else:
        continue

目前的问题是它将电子邮件写入第一个 txt。文件,但不更新第二个 txt。文件。然而,当我再次 运行 代码时,之前的数据被写入第二个 txt。这是我不太明白为什么会发生的事情,因为顺序应该是正确的。提前致谢!

更多代码在这里:

@view_config(route_name='update-data')
def update_view(request):

    m = imaplib.IMAP4_SSL('imap.gmail.com')
    m.login('gmail@gmail.com', 'password')
    m.list()
    m.select('inbox')

    result, data = m.uid('search', None, 'UNSEEN') # Only unseen mail
    
    i = len(data[0].split()) #space separate string
    
    if i == 0:
        return Response('<h3> Data cannot be updated </h3><h4>No new emails</h4><a href="localhost:8888"> Return to the main page </a> ')
    
    for x in range(i):
        latest_email_uid = data[0].split()[x]
        result, email_data = m.uid('fetch', latest_email_uid, '(RFC822)')
        raw_email = email_data[0][1]
        raw_email_string = raw_email.decode('utf-8')
        email_message = email.message_from_string(raw_email_string)

        
        
        for part in email_message.walk():
            if part.get_content_type() == 'text/plain':
                body = part.get_payload(decode=True)
                save_string = str('C:/Email/file.txt')
                myfile = open(save_string, 'a')
                myfile.write(str(body)) ## Write to file 2 and then flush this 
                open ('C:/Email/file.txt','w+') as f:
                lines = f.readlines()
                open ('C:/Email/newfile.txt','a') as g:
                g.writelines(lines[6:])
                f.close()
                g.close()
                myfile.close()# Clear first file 
            else:
                continue
                

                
                
            return Response('<h3>Data update successful</h3>')

编辑

让它按照我想要的方式工作:

for part in email_message.walk():
    if part.get_content_type() == 'text/plain':
        body = part.get_payload(decode=True)
        with open('C:/Email/file.txt', 'a') as myfile:  # Opens file.txt and writes the email body
            myfile.write(str(body)) 
        with open('C:/Email/file.txt', 'r+') as f:  # Opens file.txt again in read mode and reads lines
            lines = f.readlines()
            with open ('C:/Email/newfile.txt','a') as g: # Writes file.txt contents to newfile.txt, starting from line 6, deletes contents of the first file
                g.writelines(lines[6:])
                f.truncate(0)
    else:
        continue

您需要关闭 myfile 才能尝试重新打开它,您应该以 read 模式重新打开它。尝试这样的事情


for part in email_message.walk():
    if part.get_content_type() == 'text/plain':
        body = part.get_payload(decode=True)
        save_string = str('C:/Email/file.txt')
        myfile = open(save_string, 'a')
        myfile.write(str(body)) ## Write to file 2 and then flush this 
        <b>myfile.close()</b>
        open ('C:/Email/file.txt',<b>'r'</b>) as f:
        lines = f.readlines()
        open ('C:/Email/newfile.txt','a') as g:
        g.writelines(lines[6:])
        f.close()
        g.close()

但最好使用 with 上下文管理器打开文件,这样你就不用担心关闭文件了

for part in email_message.walk():
    if part.get_content_type() == 'text/plain':
        body = part.get_payload(decode=True)
        with open('C:/Email/file.txt', 'a') as myfile:
            myfile.write(str(body)) 
        with open('C:/Email/file.txt', 'r') as f:
            lines = f.readlines()
            with open ('C:/Email/newfile.txt','a') as g:
                g.writelines(lines[6:])

您正试图附加到此处不存在的文件:

   open ('C:/Email/newfile.txt','a') as g:
            g.writelines(lines[6:])

我建议你这样做:

if os.path.exists('C:/Email/newfile.txt'):
    g = open ('C:/Email/newfile.txt','a')
else:
    g = open ('C:/Email/newfile.txt','w+')
g.writelines(lines[6:])

让我们退后一步,评估一下代码的预期目标。您希望它基本上解析电子邮件文件的内容,然后从第 7 行及以后写入 text/plain 格式的内容。因此,我们可以安全地假设我们正在处理字符串类型。

现在,您的实现使用一个临时文件作为中间人来获取第 7 行以上。但是,您实际上可以通过解析字符串本身并获取第 7+ 行来跳过临时文件的使用。只需将字符串拆分为 \n,换行转义序列,然后从第 7+ 行重建字符串。

假设您的电子邮件部分的内容是:

>>> mystr = "This is\na message\nwith\nmultiple\nlines\nin the\nstring.\n\nEnd of file"

如果我打印这个,它会显示:

>>> print(mystr)
This is
a message
with
multiple
lines
in the
string.

End of file

您现在可以简单地拆分字符串,按 \n 拆分,其中 returns 一个列表,其中每个元素代表一行。从那里,您可以只抓取第 7 行及以后的行,然后使用 \n.

重新加入元素
>>> mystr_split = mystr.split('\n')
>>> mystr_split
['This is', 'a message', 'with', 'multiple', 'lines', 'in the', 'string.', '', 'End of file']
>>> to_write = '\n'.join(mystr_split[6:])
>>> to_write
'string.\n\nEnd of file'
>>> print(to_write)
string.

End of file

所以,回到你的问题,你可以简单地解析你的电子邮件的 text/plain 内容,并将第 7+ 行写入一个文件而不使用临时文件。

for part in email_message.walk():
    if part.get_content_type() == 'text/plain':
        body = part.get_payload(decode=True)
        save_string = r'C:/Email/file.txt'
        body_split = body.split('\n')
        to_write = '\n'.join(body_split[6:])
        with open(save_string, 'w') as f:
            f.write(to_write)