使用Python删除文件中的特定行

时间:2011-01-17 04:38:55

标签: python file input

假设我有一个充满昵称的文本文件。如何使用Python从该文件中删除特定的昵称?

18 个答案:

答案 0 :(得分:160)

首先,打开文件并从文件中获取所有行。然后以写入模式重新打开文件并将行写回,除了要删除的行:

with open("yourfile.txt", "r") as f:
    lines = f.readlines()
with open("yourfile.txt", "w") as f:
    for line in lines:
        if line.strip("\n") != "nickname_to_delete":
            f.write(line)

您需要在比较中strip("\n")换行符,因为如果您的文件不以换行符结尾,那么最后一个line也不会。

答案 1 :(得分:80)

只打开一个问题解决这个问题:

with open("target.txt", "r+") as f:
    d = f.readlines()
    f.seek(0)
    for i in d:
        if i != "line you want to remove...":
            f.write(i)
    f.truncate()

此解决方案以r / w模式(“r +”)打开文件,并使用seek重置f指针,然后截断以删除最后一次写入后的所有内容。

答案 2 :(得分:21)

最好和最快的选择,而不是将所有内容存储在列表中并重新打开文件来编写它,我认为在其他地方重新编写文件。

with open("yourfile.txt", "r") as input:
    with open("newfile.txt", "w") as output: 
        for line in input:
            if line.strip("\n") != "nickname_to_delete":
                output.write(line)

那就是它!在一个循环和一个循环只有你可以做同样的事情。它会快得多。

答案 3 :(得分:17)

这是来自 @Lother 的答案的“分叉”(我相信这应该被认为是正确答案)。


对于这样的文件:

$ cat file.txt 
1: october rust
2: november rain
3: december snow

来自Lother解决方案的这个分支工作正常:

#!/usr/bin/python3.4

with open("file.txt","r+") as f:
    new_f = f.readlines()
    f.seek(0)
    for line in new_f:
        if "snow" not in line:
            f.write(line)
    f.truncate()

改进:

  • with open,放弃使用f.close()
  • 更清晰if/else,用于评估当前行中是否存在字符串

答案 4 :(得分:4)

第一遍中读取行并在第二遍中进行更改(删除特定行)的问题是,如果文件大小很大,则RAM将耗尽。相反,更好的方法是逐行读取行,并将它们写入单独的文件中,从而消除您不需要的行。我已经使用大到12-50 GB的文件运行此方法,并且RAM使用率几乎保持不变。只有CPU周期显示正在进行的处理。

答案 5 :(得分:3)

如果您使用Linux,可以尝试以下方法 假设您有一个名为<script src="Your Path/polymer-starter-kit/bower_components/webcomponentsjs/webcomponents-lite.js"></script>的文本文件:

animal.txt

删除第一行:

$ cat animal.txt  
dog
pig
cat 
monkey         
elephant  

然后

>>> import subprocess
>>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt']) 

答案 6 :(得分:2)

我喜欢这个答案中解释的fileinput方法: Deleting a line from a text file (python)

比方说,我有一个文件中有空行,我想删除空行,这里是我解决的方法:

import fileinput
import sys
for line_number, line in enumerate(fileinput.input('file1.txt', inplace=1)):
    if len(line) > 1:
            sys.stdout.write(line)
  

注意:我的案例中的空行长度为1

答案 7 :(得分:2)

如果你把整个文件放到内存中,这不是一个好的解决方法,我知道现在每个人都有大量内存,但要考虑文件是否是几GB的日志或其他东西。

更好的方法是逐行将其复制到新文件,而不是删除第一个或类似的东西

答案 8 :(得分:2)

我认为如果您将文件读入列表,那么您可以迭代列表以查找您想要删除的昵称。您可以在不创建其他文件的情况下高效地执行此操作,但是您必须将结果写回源文件。

我可以这样做:

import, os, csv # and other imports you need
nicknames_to_delete = ['Nick', 'Stephen', 'Mark']

我假设nicknames.csv包含的数据如下:

Nick
Maria
James
Chris
Mario
Stephen
Isabella
Ahmed
Julia
Mark
...

然后将文件加载到列表中:

 nicknames = None
 with open("nicknames.csv") as sourceFile:
     nicknames = sourceFile.read().splitlines()

接下来,迭代到列表以匹配您要删除的输入:

for nick in nicknames_to_delete:
     try:
         if nick in nicknames:
             nicknames.pop(nicknames.index(nick))
         else:
             print(nick + " is not found in the file")
     except ValueError:
         pass

最后,将结果写回文件:

with open("nicknames.csv", "a") as nicknamesFile:
    nicknamesFile.seek(0)
    nicknamesFile.truncate()
    nicknamesWriter = csv.writer(nicknamesFile)
    for name in nicknames:
        nicknamesWriter.writeRow([str(name)])
nicknamesFile.close()

答案 9 :(得分:1)

可能你已经得到了正确答案,但这是我的。 我使用两个文件,而不是使用列表来收集未过滤的数据(readlines()方法做什么)。一个用于保存主数据,第二个用于在删除特定字符串时过滤数据。这是一个代码:

main_file = open('data_base.txt').read()    # your main dataBase file
filter_file = open('filter_base.txt', 'w')
filter_file.write(main_file)
filter_file.close()
main_file = open('data_base.txt', 'w')
for line in open('filter_base'):
    if 'your data to delete' not in line:    # remove a specific string
        main_file.write(line)                # put all strings back to your db except deleted
    else: pass
main_file.close()

希望你会发现这个有用! :)

答案 10 :(得分:1)

一般情况下,你不能;你必须再次写完整个文件(至少从改变点到结尾)。

在某些特定情况下,你可以做得比这更好 -

如果您的所有数据元素长度相同且没有特定的顺序,并且您知道要删除的数据元素的偏移量,则可以将最后一个项目复制到要删除的项目上并截断文件最后一项;

或者您可以使用“这是错误的数据,跳过它”值覆盖数据块,或者在保存的数据元素中保留“此项目已被删除”标记,以便您可以将其标记为已删除而无需另行修改文件。

对于短文件(100 KB以下的任何内容),这可能有点过分了。

答案 11 :(得分:0)

将文件行保存在列表中,然后删除要删除的行的列表,并将保留行写入新文件

with open("file_name.txt", "r") as f:
    lines = f.readlines() 
    lines.remove("Line you want to delete\n")
    with open("new_file.txt", "w") as new_f:
        for line in lines:        
            new_f.write(line)

答案 12 :(得分:0)

这是从文件中删除某行的一些其他方法:

src_file = zzzz.txt
f = open(src_file, "r")
contents = f.readlines()
f.close()

contents.pop(idx) # remove the line item from list, by line number, starts from 0

f = open(src_file, "w")
contents = "".join(contents)
f.write(contents)
f.close()

答案 13 :(得分:0)

我喜欢使用fileinput和'inplace'方法的这种方法:

import fileinput
for line in fileinput.input(fname, inplace =1):
    line = line.strip()
    if not 'UnwantedWord' in line:
        print(line)

与其他答案相比,它的罗word性稍差,并且速度足够快

答案 14 :(得分:0)

  

您可以使用re

假设您能够加载完整的txt文件。然后,定义一个不需要的昵称列表,然后将其替换为空字符串“”。

# Delete unwanted characters
import re

# Read, then decode for py2 compat.
path_to_file = 'data/nicknames.txt'
text = open(path_to_file, 'rb').read().decode(encoding='utf-8')

# Define unwanted nicknames and substitute them
unwanted_nickname_list = ['SourDough']
text = re.sub("|".join(unwanted_nickname_list), "", text)

答案 15 :(得分:0)

是否要从文件中删除特定行,因此使用此代码段简短的代码即可轻松删除带有句子或前缀(符号)的任何行。

with open("file_name.txt", "r") as f:
lines = f.readlines() 
with open("new_file.txt", "w") as new_f:
    for line in lines:
        if not line.startswith("write any sentence or symbol to remove line"):
            new_f.write(line)

答案 16 :(得分:-1)

获取文件的内容,将换行符拆分为元组。然后,访问元组的行号,加入结果元组,并覆盖到文件。

答案 17 :(得分:-1)

要通过文件的行号删除文件的特​​定行:

用文件名和要删除的行号替换变量文件名 line_to_delete

filename = 'foo.txt'
line_to_delete = 3
initial_line = 1
file_lines = {}

with open(filename) as f:
    content = f.readlines() 

for line in content:
    file_lines[initial_line] = line.strip()
    initial_line += 1

f = open(filename, "w")
for line_number, line_content in file_lines.items():
    if line_number != line_to_delete:
        f.write('{}\n'.format(line_content))

f.close()
print('Deleted line: {}'.format(line_to_delete))

示例输出

Deleted line: 3