Python从文件中删除行/行而不修改现有内容

时间:2016-05-19 07:52:54

标签: python

我必须根据文件中的用户输入删除字符串或字符串列表。 我提到了以下链接,事情正常。

Deleting a specific line in a file (python)

但是,上述方法读取内存中的现有文件内容,如果未找到要删除的行,则将其写回同一文件中。如果我们处理包含大量机密数据的文件,这种方法就不适合。

我想知道的是,有没有更好的方法来做同样的事情。

  valid_List=["10.1.2.3","10.2.3.4","10.2.4.5","10.2.3.7"]
  filename="abc.txt"
  for i in valid_List:
    f = open(filename,"r")
    lines = f.readlines()
    f.close()
    f = open(filename,"w")
    for line in lines:
      if line!=i+" "+ "ok"+"\n":
        #print("Writing ip not to be deleted")
        f.write(line)
      else:
        print(i," Deleted")
        user_response.append(i+" Deleted")
        logger.info('Response returned to user%s',user_response)
    f.close()

3 个答案:

答案 0 :(得分:4)

您可以读取和写入两个不同的文件,并按元素执行操作。

然后用输出文件

替换inputfile
import shutil

valid_List = ["10.1.2.3", "10.2.3.4", "10.2.4.5", "10.2.3.7"]
filename = "abc.txt"
outfile = "outfile.txt"

with open(filename, "r") as f:
    with open(outfile, "w") as o:
        for line in f:
            if all([line != "%s ok\n" % i for i in valid_List]):
                o.write(line)
            else:
                print("%s Deleted" % line.strip())

shutil.move(outfile, filename)

警告这会使用固定文件名作为输出,当您并行多次运行程序时,可能会导致冲突。如果您使用this atomic save recipe,则可以将代码简化为

valid_List = ["10.1.2.3", "10.2.3.4", "10.2.4.5", "10.2.3.7"]
filename = "abc.txt"

with atomic_open(filename, "w") as o:
    with open(filename, "r") as f:
        for line in f:
            if all([line != "%s ok\n" % i for i in valid_List]):
                o.write(line)
            else:
                print("%s Deleted" % line.strip())

这将自动为您选择一个临时文件(无冲突),并在完成时将输入文件替换为输出文件。

另外,您会注意到我已使用valid_list语句替换了您的外部循环(为all()中的每个条目打开一次文件)。这也为您节省了大量开销。

答案 1 :(得分:1)

您多次打开和关闭巨大的文件,对valid_List中的每个元素执行一次。您应该只打开一次文件并检查文件的任何一行是否与您的valid_List匹配。

尝试这样(代码未经过测试但应该可以使用):

valid_List=["10.1.2.3","10.2.3.4","10.2.4.5","10.2.3.7"]
filename="abc.txt"

f = open(filename,"r")
lines = f.readlines()
f.close()

f = open(filename,"w")
for line in lines:
    flag = True
    deleted = ''
    for i in valid_List:
        if line == i+" "+ "ok"+"\n":
            flag = False
            deleted = i
            break
    if flag:
        #print("Writing ip not to be deleted")
        f.write(line)
    else:
        print(deleted," Deleted")
f.close()  

修改
添加了对未找到的IP的检查。

valid_List=["10.1.2.3","10.2.3.4","10.2.4.5","10.2.3.7"]
filename="abc.txt"

if_found = [False for v in valid_List]

f = open(filename,"r")
lines = f.readlines()
f.close()

f = open(filename,"w")
for line in lines:
    flag = True
    deleted = ''
    for _,i in enumerate(valid_List):
        if line == i+" "+ "ok"+"\n":
            flag = False
            if_found[_] = True
            deleted = i
            break
    if flag:
        #print("Writing ip not to be deleted")
        f.write(line)
    else:
        print(deleted," Deleted")
f.close()

for _,i in enumerate(if_found):
    if not i:
        print(valid_List[_]," Not Found")

答案 2 :(得分:1)

我创建了这个脚本,基本上是将一串线串放入列表中(如果发现其中的任何一个被删除并且可以批量运行),因此它会打开多个文件,您输入的文件数显然只供个人使用而不是用户使用因为它没有输入检查,并且文件必须与脚本位于同一目录:

n=int(input('enter the number of files:'))
for i in range (1,n):
    f = open(f"{i}.txt","r")
    lines = f.readlines()
    f.close()
    f = open(f"{i}.txt","w")
    strings_to_remove=['Edited at','test']
    for line in lines:
        if line.strip() not in strings_to_remove:
            f.write(line)
    f.close()