2

我有以下代码,旨在删除文件的特​​定行。当我运行它时,它会打印目录中的两个文件名,然后删除其中的所有信息。我究竟做错了什么?我在 Windows 下使用 Python 3.2。

import os

files = [file for file in os.listdir() if file.split(".")[-1] == "txt"]

for file in files:
    print(file)
    input = open(file,"r")
    output = open(file,"w")

    for line in input:
        print(line)
        # if line is good, write it to output

    input.close()
    output.close()
4

5 回答 5

7

open(file, 'w')擦除文件。为防止这种情况发生,请以r+模式(读+写/不擦除)打开它,然后一次读取所有内容,过滤行,然后再次将它们写回。就像是

with open(file, "r+") as f:
    lines = f.readlines()              # read entire file into memory
    f.seek(0)                          # go back to the beginning of the file
    f.writelines(filter(good, lines))  # dump the filtered lines back
    f.truncate()                       # wipe the remains of the old file

我假设这good是一个告诉是否应该保留一行的函数。

于 2012-07-26T15:14:20.523 回答
3

如果您的文件适合内存,最简单的解决方案是打开文件进行读取,将其内容读取到内存,关闭文件,打开文件进行写入并将过滤后的输出写回:

with open(file_name) as f:
    lines = list(f)
# filter lines
with open(file_name, "w") as f:      # This removes the file contents
    f.writelines(lines)

由于您没有混合读取和写入操作,因此"r+"这里不需要像这样的高级文件模式,只会使事情复杂化。

如果文件不适合内存,通常的方法是将输出写入一个新的临时文件,并在处理完成后将其移回原始文件名。

于 2012-07-26T15:20:02.920 回答
1

一种方法是使用fileinputstdlib 模块。然后你不必担心打开/关闭和文件模式等......

import fileinput
from contextlib import closing
import os

fnames = [fname for fname in os.listdir() if fname.split(".")[-1] == "txt"] # use splitext
with closing(fileinput.input(fnames, inplace=True)) as fin:
    for line in fin:
        # some condition
        if 'z' not in line: # your condition here
            print line, # suppress new line but adjust for py3 - print(line, eol='') ?

使用时inplace=True- 文件输入重定向stdout到当前打开的文件。创建具有默认“.bak”扩展名的文件的备份,如果需要,它可能会派上用场。

jon@minerva:~$ cat testtext.txt
one
two
three
four
five
six
seven
eight
nine
ten

在以下条件下运行上述内容后not line.startswith('t')

jon@minerva:~$ cat testtext.txt
one
four
five
six
seven
eight
nine
于 2012-07-26T15:58:53.203 回答
0

当您打开文件写入文件时,您正在删除所有内容。您不能同时对文件进行打开读取和写入。改为使用open(file,"r+"),然后在写入任何内容之前将所有行保存到另一个变量。

于 2012-07-26T15:18:04.927 回答
0

您不应该同时打开同一个文件进行读取和写入。

“w”表示创建一个空的写作。如果该文件已存在,则其数据将被删除。

因此,您可以使用不同的文件名进行写入。

于 2012-07-26T15:18:22.323 回答