Python에서 텍스트 파일의 특정 줄 편집


88

다음을 포함하는 텍스트 파일이 있다고 가정 해 보겠습니다.

Dan
Warrior
500
1
0

해당 텍스트 파일의 특정 줄을 편집 할 수있는 방법이 있습니까? 지금 나는 이것을 가지고있다 :

#!/usr/bin/env python
import io

myfile = open('stats.txt', 'r')
dan = myfile.readline()
print dan
print "Your name: " + dan.split('\n')[0]

try:
    myfile = open('stats.txt', 'a')
    myfile.writelines('Mage')[1]
except IOError:
        myfile.close()
finally:
        myfile.close()

네, 그것이 myfile.writelines('Mage')[1]틀렸다는 것을 압니다 . 하지만 당신은 내 요점을 알죠? Warrior를 Mage로 대체하여 2 행을 편집하려고합니다. 하지만 그렇게 할 수 있습니까?


1
: 나는 당신을 위해 무엇을 찾고있는 사람이 게시물 커버 생각 stackoverflow.com/questions/1998233/...
카일 와일드

1
이런 종류의 일을 많이해야한다면이 파일을 텍스트에서 bdb 또는 다른 bdb와 유사한 것으로 변환하는 것이 좋습니다.
Nick Bastin 2011 년

답변:


125

다음과 같이하고 싶습니다.

# with is like your try .. finally block in this case
with open('stats.txt', 'r') as file:
    # read a list of lines into data
    data = file.readlines()

print data
print "Your name: " + data[0]

# now change the 2nd line, note that you have to add a newline
data[1] = 'Mage\n'

# and write everything back
with open('stats.txt', 'w') as file:
    file.writelines( data )

그 이유는 파일에서 직접 "change line 2"와 같은 작업을 수행 할 수 없기 때문입니다. 파일의 일부만 덮어 쓸 수 있습니다 (삭제할 수 없음). 즉, 새 콘텐츠가 이전 콘텐츠를 덮을뿐입니다. 따라서 2 행 위에 'Mage'를 썼다면 결과 행은 'Mageior'가됩니다.


2
안녕하세요 Jochen, "with open (filename, mode)"는 프로그램이 종료 된 후 파일 이름을 암시 적으로 닫습니다.
Radu

@Gabriel Thx, 그것은 여전히 ​​with ... as file 문을 사용하지 않지만 주목해야 할 중요합니다. 파이썬 여부, 나는 :) 그것을 좋아하지 않는다
라두

@Radu 그것은 그것에 익숙해지는 문제입니다. 나는 또한 수동으로 열린 파일을 닫는 데 사용 close.했지만 이제 with블록 을 사용하는 것이 훨씬 깨끗 하다는 것을 알 수 있습니다.
Gabriel

5
이것이 작은 파일에 선호되는 솔루션이라고 가정하는 것이 맞습니까? 그렇지 않으면 데이터를 저장하기 위해 많은 메모리가 필요할 수 있습니다. 더욱이, 한 번의 편집이라도 전체를 다시 작성해야합니다.
Arindam Roychowdhury

11
나쁜 .. 20Gb 파일이 있으면 어떨까요?
Brans Ds

21

fileinput을 사용하여 내부 편집을 수행 할 수 있습니다.

import fileinput
for  line in fileinput.FileInput("myfile", inplace=1):
    if line .....:
         print line

19
def replace_line(file_name, line_num, text):
    lines = open(file_name, 'r').readlines()
    lines[line_num] = text
    out = open(file_name, 'w')
    out.writelines(lines)
    out.close()

그리고:

replace_line('stats.txt', 0, 'Mage')

9
이렇게하면 전체 파일의 내용이 메모리에로드되므로 파일이 크면 좋지 않을 수 있습니다.
Steve Ng 2014

@SteveNg 발견 한 문제에 대한 해결책이 있습니까? 이 답변과 수락 된 답변은 모두 전체 파일을 메모리에로드하는 데 의존합니다
Blupon

14

두 가지 방법으로 수행 할 수 있으며 요구 사항에 맞는 것을 선택할 수 있습니다.

방법 I.) 줄 번호를 사용하여 바꾸기. 내장 기능을 사용할 수 있습니다.enumerate()이 경우 를 .

먼저 읽기 모드 에서 모든 데이터를 변수로 가져옵니다.

with open("your_file.txt",'r') as f:
    get_all=f.readlines()

둘째, 파일에 쓰기 ( 열거 가 실행 되는 위치 )

with open("your_file.txt",'w') as f:
    for i,line in enumerate(get_all,1):         ## STARTS THE NUMBERING FROM 1 (by default it begins with 0)    
        if i == 2:                              ## OVERWRITES line:2
            f.writelines("Mage\n")
        else:
            f.writelines(line)

방법 II.) 교체 할 키워드 사용 :

읽기 모드 에서 파일을 열고 내용을 목록에 복사

with open("some_file.txt","r") as f:
    newline=[]
    for word in f.readlines():        
        newline.append(word.replace("Warrior","Mage"))  ## Replace the keyword while you copy.  

"Warrior"가 "Mage"로 대체되었으므로 업데이트 된 데이터를 파일에 씁니다.

with open("some_file.txt","w") as f:
    for line in newline:
        f.writelines(line)

두 경우 모두 다음과 같이 출력 됩니다.

Dan                   Dan           
Warrior   ------>     Mage       
500                   500           
1                     1   
0                     0           

3

텍스트에 개인이 한 명만 포함 된 경우 :

import re

# creation
with open('pers.txt','wb') as g:
    g.write('Dan \n Warrior \n 500 \r\n 1 \r 0 ')

with open('pers.txt','rb') as h:
    print 'exact content of pers.txt before treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt before treatment:\n',h.read()


# treatment
def roplo(file_name,what):
    patR = re.compile('^([^\r\n]+[\r\n]+)[^\r\n]+')
    with open(file_name,'rb+') as f:
        ch = f.read()
        f.seek(0)
        f.write(patR.sub('\\1'+what,ch))
roplo('pers.txt','Mage')


# after treatment
with open('pers.txt','rb') as h:
    print '\nexact content of pers.txt after treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt after treatment:\n',h.read()

텍스트에 여러 개인이 포함 된 경우 :

다시 가져 오기

# creation
with open('pers.txt','wb') as g:
    g.write('Dan \n Warrior \n 500 \r\n 1 \r 0 \n Jim  \n  dragonfly\r300\r2\n10\r\nSomo\ncosmonaut\n490\r\n3\r65')

with open('pers.txt','rb') as h:
    print 'exact content of pers.txt before treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt before treatment:\n',h.read()


# treatment
def ripli(file_name,who,what):
    with open(file_name,'rb+') as f:
        ch = f.read()
        x,y = re.search('^\s*'+who+'\s*[\r\n]+([^\r\n]+)',ch,re.MULTILINE).span(1)
        f.seek(x)
        f.write(what+ch[y:])
ripli('pers.txt','Jim','Wizard')


# after treatment
with open('pers.txt','rb') as h:
    print 'exact content of pers.txt after treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt after treatment:\n',h.read()

개인의 "직업"이 텍스트에서 일정한 길이 인 경우 원하는 개인의 "직업"에 해당하는 텍스트 부분 만 변경할 수 있습니다. 이는 보낸 사람의 것과 동일한 아이디어입니다.

그러나 나에 따르면 cPickle을 사용하여 파일에 기록 된 사전에 개인의 특성을 넣는 것이 더 좋습니다.

from cPickle import dump, load

with open('cards','wb') as f:
    dump({'Dan':['Warrior',500,1,0],'Jim':['dragonfly',300,2,10],'Somo':['cosmonaut',490,3,65]},f)

with open('cards','rb') as g:
    id_cards = load(g)
print 'id_cards before change==',id_cards

id_cards['Jim'][0] = 'Wizard'

with open('cards','w') as h:
    dump(id_cards,h)

with open('cards') as e:
    id_cards = load(e)
print '\nid_cards after change==',id_cards

2

나는 오늘 저녁 파일 작업을 연습하고 있으며 반복 / 다중 사용을 위해 더 큰 기능을 제공하기 위해 Jochen의 답변을 구축 할 수 있다는 것을 깨달았습니다. 불행히도 내 대답은 큰 파일을 다루는 문제를 다루지 않지만 작은 파일에서 삶을 더 쉽게 만듭니다.

with open('filetochange.txt', 'r+') as foo:
    data = foo.readlines()                  #reads file as list
    pos = int(input("Which position in list to edit? "))-1  #list position to edit
    data.insert(pos, "more foo"+"\n")           #inserts before item to edit
    x = data[pos+1]
    data.remove(x)                      #removes item to edit
    foo.seek(0)                     #seeks beginning of file
    for i in data:
        i.strip()                   #strips "\n" from list items
        foo.write(str(i))

0

이것이 가장 쉬운 방법입니다.

fin = open("a.txt")
f = open("file.txt", "wt")
for line in fin:
    f.write( line.replace('foo', 'bar') )
fin.close()
f.close()

나는 그것이 당신에게 효과가 있기를 바랍니다.


-1
#read file lines and edit specific item

file=open("pythonmydemo.txt",'r')
a=file.readlines()
print(a[0][6:11])

a[0]=a[0][0:5]+' Ericsson\n'
print(a[0])

file=open("pythonmydemo.txt",'w')
file.writelines(a)
file.close()
print(a)

1
Stack Overflow에 오신 것을 환영합니다! 매우 오래되고 이미 답변 된 질문에 답변하고 있습니다. 다음은 응답 방법에 대한 가이드입니다 .
help-info.de

@ ajay-jaiswal 질문을 지정하고 재현 가능한 최소한의 예와 표시되는 오류 메시지를 제공하십시오. 코드를 게시했지만 실제 질문은 게시하지 않았습니다.
dmitryro

-2

file_name다음과 같은 이름의 파일이 있다고 가정합니다 .

this is python
it is file handling
this is editing of line

2 번 줄을 "수정 완료"로 바꿔야합니다.

f=open("file_name","r+")
a=f.readlines()
for line in f:
   if line.startswith("rai"):
      p=a.index(line)
#so now we have the position of the line which to be modified
a[p]="modification is done"
f.seek(0)
f.truncate() #ersing all data from the file
f.close()
#so now we have an empty file and we will write the modified content now in the file
o=open("file_name","w")
for i in a:
   o.write(i)
o.close()
#now the modification is done in the file
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.