답변:
먼저 파일을 열고 파일에서 모든 줄을 가져옵니다. 그런 다음 파일을 쓰기 모드로 다시 열고 삭제하려는 줄을 제외하고 줄을 다시 쓰십시오.
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- 포인터를 재설정 한 다음 잘라서 마지막 쓰기 후 모든 것을 제거합니다.
for루프에 오류가 발생 하면 부분적으로 덮어 쓴 파일이 생겨서 줄이 중복되거나 줄이 반으로 줄어 듭니다. 대신 에 f.truncate()바로 원할 수도 있습니다 f.seek(0). 그렇게하면 오류가 발생하면 불완전한 파일로 끝납니다. 그러나 실제 솔루션 (디스크 공간이있는 경우)은 임시 파일로 출력 한 다음 모든 것이 성공한 후에 원본 파일을 사용 os.replace()하거나 pathlib.Path(temp_filename).replace(original_filename)원본 파일 로 바꾸는 것입니다.
i.strip('\n') != "line you want to remove..."허용 된 답변에 언급 된대로 추가하면 내 문제를 완벽하게 해결할 수 있습니다. i나를 위해 아무것도하지 않았기 때문에
목록에 모든 것을 저장하고 파일을 쓰기 위해 파일을 다시 여는 것이 아니라 가장 빠르고 빠른 옵션은 다른 곳에서 파일을 다시 쓰는 것입니다.
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)
그게 다야! 하나의 루프에서 하나만 동일한 작업을 수행 할 수 있습니다. 훨씬 빠를 것입니다.
(output.write(line) for line in input if line!="nickname_to_delete"+"\n")
subprocess.call(['mv', 'newfile.txt', 'yourfile.txt'])
os.replace(python v 3.3의 새로운 기능)은에 대한 시스템 호출보다 크로스 플랫폼 mv입니다.
이것은 @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문자열이 현재 줄에 없는지 평가하기 위해 더 명확 합니다.이 답변에서 설명한 파일 입력 방식이 마음에 들었습니다 . 텍스트 파일에서 줄 삭제 (파이썬)
예를 들어 빈 줄이 들어있는 파일이 있고 빈 줄을 제거하고 싶다고 가정 해 보겠습니다.
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
첫 번째 줄을 삭제하십시오.
>>> import subprocess
>>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt'])
그때
$ cat animal.txt
pig
cat
monkey
elephant
파일을 목록으로 읽으면 목록에서 반복하여 제거하려는 닉네임을 찾을 수 있다고 생각합니다. 추가 파일을 만들지 않고도 훨씬 효율적으로 수행 할 수 있지만 결과를 소스 파일에 다시 써야합니다.
이 작업을 수행하는 방법은 다음과 같습니다.
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()
일반적으로, 당신은 할 수 없습니다; 전체 파일을 다시 작성해야합니다 (적어도 변경 시점에서 끝까지).
어떤 경우에는 이것보다 더 잘 할 수 있습니다-
모든 데이터 요소의 길이가 동일하고 특정 순서가없는 경우 제거하려는 요소의 오프셋을 알고 있으면 삭제할 항목 위에 마지막 항목을 복사하고 마지막 항목 전에 파일을자를 수 있습니다 ;
또는 데이터 청크를 '이것은 잘못된 데이터입니다. 건너 뛰십시오'값으로 덮어 쓰거나 저장된 데이터 요소에 '이 항목이 삭제되었습니다'플래그를 유지하여 파일을 수정하지 않고 삭제 된 것으로 표시 할 수 있습니다.
이것은 짧은 문서 (100KB 미만의 문서)에는 과잉 일 수 있습니다.
아마, 당신은 이미 정답을 얻었지만 여기에 내 것이 있습니다. 필터링되지 않은 데이터를 수집하기 위해 목록을 사용하는 대신 ( 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()
이 정보가 도움이 되길 바랍니다. :)
파일 줄을 목록에 저장 한 다음 삭제하려는 줄을 목록에서 제거하고 나머지 줄을 새 파일에 씁니다.
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)
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)
줄 번호 로 파일의 특정 줄을 삭제하려면 :
변수 filename 및 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
for nb, line in enumerate(f.readlines())
파일의 내용을 가져와 줄 바꿈으로 튜플로 나눕니다. 그런 다음 튜플의 줄 번호에 액세스하고 결과 튜플에 가입 한 다음 파일을 덮어 씁니다.
tuple(f.read().split('\n'))?? (2) "튜플의 행 번호에 액세스하십시오"및 "결과 튜플에 참여하십시오"는 다소 신비한 소리입니다. 실제 파이썬 코드는 더 이해하기 쉽습니다.
fileinput@ jf-sebastian 여기에 설명 된대로 시도 하십시오 . 간단한for구문 으로 임시 파일을 통해 한 줄씩 작업 할 수있는 것으로 보입니다 .