답변:
먼저 파일을 열고 파일에서 모든 줄을 가져옵니다. 그런 다음 파일을 쓰기 모드로 다시 열고 삭제하려는 줄을 제외하고 줄을 다시 쓰십시오.
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
구문 으로 임시 파일을 통해 한 줄씩 작업 할 수있는 것으로 보입니다 .