2009-08-25 23 views
30

Tôi có một tập tin văn bản mà trông như thế này:Chèn dòng tại vị trí xác định của một Text File

blah blah 
foo1 bar1 
foo1 bar2 
foo1 bar3 
foo2 bar4 
foo2 bar5 
blah blah 

Bây giờ tôi muốn chèn 'foo bar' giữa 'foo1 bar3''foo2 bar4'.

Đây là cách tôi đã làm nó:

import shutil 

txt = '1.txt' 
tmptxt = '1.txt.tmp' 

with open(tmptxt, 'w') as outfile: 
    with open(txt, 'r') as infile: 
     flag = 0 
     for line in infile: 
      if not line.startswith('foo1') and flag == 0: 
       outfile.write(line) 
       continue 
      if line.startswith('foo1') and flag == 0: 
       flag = 1 
       outfile.write(line) 
       continue 
      if line.startswith('foo1') and flag == 1: 
       outfile.write(line) 
       continue 
      if not line.startswith('foo1') and flag == 1: 
       outfile.write('foo bar\n') 
       outfile.write(line) 
       flag = 2 
       continue 
      if not line.startswith('foo1') and flag == 2: 
       outfile.write(line) 
       continue 

shutil.move(tmptxt, txt) 

này làm việc cho tôi, nhưng trông khá xấu xí.

Trả lời

55

Cách tốt nhất để làm cho "pseudo-inplace" thay đổi cho một tập tin trong Python là với các module fileinput từ thư viện tiêu chuẩn:

import fileinput 

processing_foo1s = False 

for line in fileinput.input('1.txt', inplace=1): 
    if line.startswith('foo1'): 
    processing_foo1s = True 
    else: 
    if processing_foo1s: 
     print 'foo bar' 
    processing_foo1s = False 
    print line, 

Bạn cũng có thể chỉ định một phần mở rộng sao lưu nếu bạn muốn giữ lại phiên bản cũ xung quanh, nhưng điều này làm việc trong cùng một tĩnh mạch như mã của bạn - sử dụng .bak làm phần mở rộng sao lưu nhưng cũng loại bỏ nó sau khi thay đổi đã hoàn tất thành công. Ngoài việc sử dụng đúng mô-đun thư viện chuẩn, mã này sử dụng logic đơn giản hơn: để chèn một dòng "foo bar" sau mỗi lần chạy bắt đầu bằng foo1, boolean là tất cả những gì bạn cần (tôi có đang chạy hay không?) Và các bool trong câu hỏi có thể được thiết lập vô điều kiện chỉ dựa trên cho dù dòng hiện tại bắt đầu theo cách đó hay không. Nếu logic chính xác mà bạn mong muốn hơi khác so với logic này (đó là những gì tôi suy ra từ mã của bạn), nó sẽ không khó để tinh chỉnh mã này cho phù hợp.

9

Nhớ lại rằng một trình lặp là một đối tượng hạng nhất. Nó có thể được sử dụng trong nhiều câu hỏi cho các câu hỏi.

Dưới đây là một cách để xử lý điều này mà không có nhiều câu lệnh if và cờ phức tạp.

with open(tmptxt, 'w') as outfile: 
    with open(txt, 'r') as infile: 
     rowIter= iter(infile) 
     for row in rowIter: 
      if row.startswith('foo2'): # Start of next section 
       break 
      print row.rstrip(), repr(row) 
     print "foo bar" 
     print row 
     for row in rowIter: 
      print row.rstrip() 
+0

Cảm ơn các cách tiếp cận hoàn toàn khác nhau. –

13

Thích ứng dụ Alex Martelli của:

import fileinput 
for line in fileinput.input('1.txt', inplace=1): 
print line, 
if line.startswith('foo1 bar3'): 
    print 'foo bar' 
Các vấn đề liên quan