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

Python delete line/lines from file without modifying existing contents

我必须从文件中删除基于用户输入的字符串或字符串列表。我提到了下面的链接,一切正常。

删除文件中的特定行(python)

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  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"+"
"
:
        #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()


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

然后用输出文件替换输入文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
"
% i for i in valid_List]):
                o.write(line)
            else:
                print("%s Deleted" % line.strip())

shutil.move(outfile, filename)

警告:这将使用一个固定的输出文件名,当您并行运行程序多次时,这可能会导致冲突。如果使用这个原子保存方法,可以将代码简化为

1
2
3
4
5
6
7
8
9
10
11
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
"
% i for i in valid_List]):
                o.write(line)
            else:
                print("%s Deleted" % line.strip())

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

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


我创建了这个脚本,基本上你把一堆行字符串放在一个列表中,如果发现它们中的任何一个被删除,它会批量运行,所以它会打开多个文件,你输入的文件数量很明显是仅供个人使用,而不是用户,因为它没有输入检查,文件需要与脚本在同一个目录中:

1
2
3
4
5
6
7
8
9
10
11
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()


您多次打开和关闭这个巨大的文件,对于valid_list中的每个元素一次。相反,您应该只打开一次文件,检查是否有任何一行文件与您的valid_list匹配。

尝试这样做(代码没有测试,但应该可以工作):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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"+"
"
:
            flag = False
            deleted = i
            break
    if flag:
        #print("Writing ip not to be deleted")
        f.write(line)
    else:
        print(deleted," Deleted")
f.close()

编辑添加了对未找到IP的检查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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"+"
"
:
            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")