IT박스

파일에서 특정 줄을 삭제하기 위해 Python 사용

itboxs 2020. 7. 8. 08:06
반응형

파일에서 특정 줄을 삭제하기 위해 Python 사용


별명으로 가득 찬 텍스트 파일이 있다고 가정 해 봅시다. Python을 사용하여이 파일에서 특정 닉네임을 삭제하려면 어떻게해야합니까?


먼저 파일을 열고 파일에서 모든 줄을 가져옵니다. 그런 다음 파일을 쓰기 모드로 다시 열고 삭제하려는 줄을 제외하고 줄을 다시 쓰십시오.

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하지 않습니다 중 하나를.


한 번만 열면이 문제에 대한 해결책 :

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 +")로 열고 탐색을 사용하여 f- 포인터를 재설정 한 다음 잘라서 마지막 쓰기 후 모든 것을 제거합니다.


목록에 모든 것을 저장하고 파일을 쓰기 위해 파일을 다시 여는 것이 아니라 가장 빠르고 빠른 옵션은 다른 곳에서 파일을 다시 쓰는 것입니다.

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)

그게 다야! 하나의 루프에서 하나만 동일한 작업을 수행 할 수 있습니다. 훨씬 빠를 것입니다.


이것은 @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문자열이 현재 줄에 없는지 평가하기 위해 더 명확 합니다.

첫 번째 패스에서 행을 읽고 두 번째 패스에서 변경 (특정 행 삭제)하는 문제는 파일 크기가 너무 크면 RAM이 부족하다는 것입니다. 대신, 더 나은 방법은 줄을 하나씩 읽고 별도의 파일에 작성하여 필요없는 줄을 제거하는 것입니다. 12-50GB의 파일 로이 접근법을 실행했으며 RAM 사용량은 거의 일정합니다. CPU 주기만 처리가 진행 중임을 보여줍니다.


이 답변에서 설명한 파일 입력 방식이 마음에 들었습니다 . 텍스트 파일에서 줄 삭제 (파이썬)

예를 들어 빈 줄이 들어있는 파일이 있고 빈 줄을 제거하고 싶다고 가정 해 보겠습니다.

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입니다.


Linux를 사용하는 경우 다음 접근 방식을 시도 할 수 있습니다.
다음과 같은 이름의 텍스트 파일이 있다고 가정하십시오 animal.txt.

$ cat animal.txt  
dog
pig
cat 
monkey         
elephant  

Delete the first line:

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

then

$ cat animal.txt
pig
cat
monkey
elephant

I think if you read the file into a list, then do the you can iterate over the list to look for the nickname you want to get rid of. You can do it much efficiently without creating additional files, but you'll have to write the result back to the source file.

Here's how I might do this:

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

I'm assuming nicknames.csv contains data like:

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

Then load the file into the list:

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

Next, iterate over to list to match your inputs to delete:

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

Lastly, write the result back to file:

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()

Not a good solve if u put a whole file to memory, i know nowadays everyone have tons of memory, but consider if the file is several GB of logs or something.

Better way copy it line by line to a new file, than delete the first or something like that


In general, you can't; you have to write the whole file again (at least from the point of change to the end).

In some specific cases you can do better than this -

if all your data elements are the same length and in no specific order, and you know the offset of the one you want to get rid of, you could copy the last item over the one to be deleted and truncate the file before the last item;

or you could just overwrite the data chunk with a 'this is bad data, skip it' value or keep a 'this item has been deleted' flag in your saved data elements such that you can mark it deleted without otherwise modifying the file.

This is probably overkill for short documents (anything under 100 KB?).


Probably, you already got a correct answer, but here is mine. Instead of using a list to collect unfiltered data (what readlines() method does), I use two files. One is for hold a main data, and the second is for filtering the data when you delete a specific string. Here is a code:

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()

Hope you will find this useful! :)


Save the file lines in a list, then remove of the list the line you want to delete and write the remain lines to a new file

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)

here's some other method to remove a/some line(s) from a file:

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()

I like this method using fileinput and the 'inplace' method:

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

It's a little less wordy than the other answers and is fast enough for


You can use the re library

Assuming that you are able to load your full txt-file. You then define a list of unwanted nicknames and then substitute them with an empty string "".

# 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)

Take the contents of the file, split it by newline into a tuple. Then, access your tuple's line number, join your result tuple, and overwrite to the file.

참고URL : https://stackoverflow.com/questions/4710067/using-python-for-deleting-a-specific-line-in-a-file

반응형