텍스트 파일을 수정하는 방법
Python을 사용하고 있는데 파일을 삭제하거나 복사하지 않고 텍스트 파일에 문자열을 삽입하고 싶습니다.내가 어떻게 그럴 수 있을까?
유감스럽게도 파일을 다시 쓰지 않고서는 파일 중간에 삽입할 수 없습니다.이전 포스터에서 알 수 있듯이, 파일에 추가하거나 seek를 사용하여 파일의 일부를 덮어쓸 수 있지만, 처음이나 중간에 내용을 추가하려면 파일을 다시 작성해야 합니다.
이것은 Python이 아니라 운영체제에 관한 것입니다.그것은 모든 언어에서 같다.
제가 주로 하는 일은 파일을 읽고 수정한 후 myfile이라는 새로운 파일에 쓰는 것입니다.txt.tmp 같은 거요파일 전체를 메모리에 읽어 들이는 것보다 파일이 너무 클 수 있습니다.임시 파일이 완성되면 원래 파일과 동일하게 이름을 변경합니다.
파일 쓰기가 어떤 이유로 크래시 또는 중단되어도 원래 파일이 그대로 남아 있기 때문에 이 방법은 효과적이고 안전한 방법입니다.
네가 뭘 하고 싶은지에 달렸어.첨부하려면 "a"로 열 수 있습니다.
with open("foo.txt", "a") as f:
f.write("new line\n")
파일에서 먼저 읽어야 할 내용을 미리 보고 싶은 경우:
with open("foo.txt", "r+") as f:
old = f.read() # read everything in the file
f.seek(0) # rewind
f.write("new line\n" + old) # write the new line before
inplace=1 매개 변수를 사용하면 Python 표준 라이브러리의 모듈이 파일을 inplace로 다시 씁니다.
import sys
import fileinput
# replace all occurrences of 'sit' with 'SIT' and insert a line after the 5th
for i, line in enumerate(fileinput.input('lorem_ipsum.txt', inplace=1)):
sys.stdout.write(line.replace('sit', 'SIT')) # replace 'sit' and write
if i == 4: sys.stdout.write('\n') # write a blank line after the 5th line
대부분의 경우 파일을 다시 쓰려면 이전 복사본을 수정된 이름으로 저장합니다.Unix 사용자는~
오래된 것을 표시하기 위해서요.Windows 사용자는 .bak 또는 .old를 추가하거나 파일 이름을 완전히 바꾸거나 이름 앞에 ~을 붙입니다.
import shutil
shutil.move(afile, afile + "~")
destination= open(aFile, "w")
source= open(aFile + "~", "r")
for line in source:
destination.write(line)
if <some condition>:
destination.write(<some additional line> + "\n")
source.close()
destination.close()
대신shutil
, 다음을 사용할 수 있습니다.
import os
os.rename(aFile, aFile + "~")
Python의 mmap 모듈을 사용하면 파일에 삽입할 수 있습니다.다음 예시는 Unix에서 실행하는 방법을 보여 줍니다(Windows mmap은 다를 수 있습니다).이로 인해 모든 오류 조건이 처리되는 것은 아니며 원본 파일이 손상되거나 손실될 수 있습니다.또한 유니코드 문자열도 처리할 수 없습니다.
import os
from mmap import mmap
def insert(filename, str, pos):
if len(str) < 1:
# nothing to insert
return
f = open(filename, 'r+')
m = mmap(f.fileno(), os.path.getsize(filename))
origSize = m.size()
# or this could be an error
if pos > origSize:
pos = origSize
elif pos < 0:
pos = 0
m.resize(origSize + len(str))
m[pos+len(str):] = m[pos:origSize]
m[pos:pos+len(str)] = str
m.close()
f.close()
또한 'r+' 모드에서 파일을 연 상태에서 mmap 없이 이 작업을 수행할 수도 있지만, 삽입 위치에서 EOF까지 파일의 내용을 읽고 임시로 저장해야 하므로 편리성과 효율성이 떨어집니다.
Adam이 언급한 바와 같이 모든 메모리를 메모리 교환 및 재기입할 수 있는 충분한 메모리가 있는지 여부를 판단하기 전에 시스템 제한을 고려해야 합니다.
작은 파일을 사용하고 있거나 메모리 문제가 없는 경우, 다음과 같이 도움이 됩니다.
옵션 1) 파일 전체를 메모리에 읽어 들여 행 전체 또는 일부에 regex 치환을 실행한 후 해당 행과 추가 행으로 바꿉니다.파일내에서 「중간선」이 일의인 것을 확인하거나, 각 행에 타임스탬프가 있는 경우는, 신뢰성이 높은 것을 확인할 필요가 있습니다.
# open file with r+b (allow write and binary mode)
f = open("file.log", 'r+b')
# read entire content of file into memory
f_content = f.read()
# basically match middle line and replace it with itself and the extra line
f_content = re.sub(r'(middle line)', r'\1\nnew line', f_content)
# return pointer to top of file so we can re-write the content with replaced string
f.seek(0)
# clear file content
f.truncate()
# re-write the content with the updated content
f.write(f_content)
# close file
f.close()
옵션 2) 중간선을 찾아 해당 선과 추가 선으로 바꿉니다.
# open file with r+b (allow write and binary mode)
f = open("file.log" , 'r+b')
# get array of lines
f_content = f.readlines()
# get middle line
middle_line = len(f_content)/2
# overwrite middle line
f_content[middle_line] += "\nnew line"
# return pointer to top of file so we can re-write the content with replaced string
f.seek(0)
# clear file content
f.truncate()
# re-write the content with the updated content
f.write(''.join(f_content))
# close file
f.close()
깔끔하게 한 것에 대해 작은 반을 썼습니다.
import tempfile
class FileModifierError(Exception):
pass
class FileModifier(object):
def __init__(self, fname):
self.__write_dict = {}
self.__filename = fname
self.__tempfile = tempfile.TemporaryFile()
with open(fname, 'rb') as fp:
for line in fp:
self.__tempfile.write(line)
self.__tempfile.seek(0)
def write(self, s, line_number = 'END'):
if line_number != 'END' and not isinstance(line_number, (int, float)):
raise FileModifierError("Line number %s is not a valid number" % line_number)
try:
self.__write_dict[line_number].append(s)
except KeyError:
self.__write_dict[line_number] = [s]
def writeline(self, s, line_number = 'END'):
self.write('%s\n' % s, line_number)
def writelines(self, s, line_number = 'END'):
for ln in s:
self.writeline(s, line_number)
def __popline(self, index, fp):
try:
ilines = self.__write_dict.pop(index)
for line in ilines:
fp.write(line)
except KeyError:
pass
def close(self):
self.__exit__(None, None, None)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
with open(self.__filename,'w') as fp:
for index, line in enumerate(self.__tempfile.readlines()):
self.__popline(index, fp)
fp.write(line)
for index in sorted(self.__write_dict):
for line in self.__write_dict[index]:
fp.write(line)
self.__tempfile.close()
그런 다음 다음과 같이 사용할 수 있습니다.
with FileModifier(filename) as fp:
fp.writeline("String 1", 0)
fp.writeline("String 2", 20)
fp.writeline("String 3") # To write at the end of the file
UNIX 를 알고 있는 경우는, 다음의 조작을 실시해 주세요.
주의: $는 명령 프롬프트를 의미합니다.
my_data 파일이 있다고 가정합니다.txt에 다음과 같은 내용을 포함합니다.
$ cat my_data.txt
This is a data file
with all of my data in it.
후, 「 」를 사용해 주세요.os
은 일반 할 수 .sed
, 명령어
import os
# Identifiers used are:
my_data_file = "my_data.txt"
command = "sed -i 's/all/none/' my_data.txt"
# Execute the command
os.system(command)
SED에 대해 모르신다면, 확인해보세요. 매우 유용합니다.
언급URL : https://stackoverflow.com/questions/125703/how-to-modify-a-text-file
'sourcecode' 카테고리의 다른 글
MySQL에서 Lock wait timeout exceededed를 디버깅하는 방법 (0) | 2023.01.10 |
---|---|
MySQL의 외부 키 기본 사항 (0) | 2023.01.10 |
JSON 오브젝트 작성 방법 (0) | 2023.01.10 |
Javascript(글로벌 변수 포함)의 변수 선언 구문의 차이는? (0) | 2022.12.26 |
perl - 2개의 데이터베이스에서 2개의 SQL 쿼리로 이루어진 2개의 열을 비교합니다. (0) | 2022.12.26 |