2010-01-26 44 views
10

Tôi có tệp cấu hình mà tôi muốn thêm một chuỗi, trông giống như ví dụ: như thế:Cách chèn một chuỗi vào một văn bản

line1 
line2 
line3 
line4 

Chuỗi mới không được nối thêm nhưng được viết ở đâu đó giữa tệp. Vì vậy, tôi đang tìm kiếm một vị trí cụ thể (hoặc chuỗi) trong file và khi nó đã được tìm thấy, tôi chèn chuỗi mới của tôi:

file = File.open(path,"r+") 
while (!file.eof?) 
    line = file.readline 
    if (line.downcase.starts_with?("line1")) 
    file.write("Some nice little sentence") 
    end 
end 

Vấn đề là rằng Ruby ghi đè dòng ở vị trí đó với văn bản mới , vì vậy kết quả là như sau:

line1 
Some nice little sentence 
line3 
line4 

những gì tôi muốn là một "thực" chèn:

line1 
Some nice little sentence 
line2 
line3 
line4 

Làm thế nào điều này có thể đạt được?

Trả lời

11

Nếu đó là một tập tin nhỏ Tôi nghĩ rằng cách dễ nhất sẽ được:

  • Đọc tệp hoàn chỉnh.
  • Chèn dòng.
  • Viết tệp mới.

Đó là cách Rails does it phía sau hậu trường.

Hoặc bạn có thể sao chép nó từng dòng và sau đó ghi đè lên bản gốc với mv như thế này:

require 'fileutils' 

tempfile=File.open("file.tmp", 'w') 
f=File.new("file.txt") 
f.each do |line| 
    tempfile<<line 
    if line.downcase=~/^line2/ 
    tempfile << "Some nice little sentence\n" 
    end 
end 
f.close 
tempfile.close 

FileUtils.mv("file.tmp", "file.txt") 
0

Cách dễ nhất là đọc toàn bộ tệp trong bộ nhớ, sau đó viết phần đầu tiên trở lại tệp, viết dòng đã chèn vào tệp và viết phần còn lại vào tệp. Việc này khá đơn giản khi bạn đọc tệp dưới dạng một mảng các dòng, nhưng bạn có thể gặp phải sự cố nếu tệp của bạn quá lớn vì bạn phải đọc toàn bộ tệp vào bộ nhớ bằng cách tiếp cận này. Ngoài ra, bạn có thể tìm thấy vị trí mà bạn muốn chèn dòng, đọc các dòng sau điểm đó vào bộ nhớ, tìm lại điểm đó trong tệp, viết dòng mới của bạn vào tệp và cuối cùng viết các dòng còn lại vào tệp. Một lần nữa bạn sẽ gặp phải vấn đề nếu phần còn lại của tệp rất lớn vì bạn phải đọc tất cả vào bộ nhớ.

Cách tiếp cận thứ ba là viết phần đầu tiên vào tệp mới, viết dòng được chèn vào tệp mới, ghi phần còn lại của tệp gốc vào tệp mới và cuối cùng thay tệp cũ bằng tệp mới hệ thống tệp. Cách tiếp cận này cho phép bạn xử lý một dòng tại một thời điểm để bạn có thể xử lý các tệp không phù hợp với bộ nhớ.

Lý do tại sao tệp viết hoạt động như thế này là vì tệp giống như một mảng có kích thước cố định của byte: khi bạn ghi byte vào tệp, bạn sẽ ghi đè byte hiện có (tôi bỏ qua trường hợp bạn thêm vào một tệp ở đây). Vì vậy, cách duy nhất để chèn bất kỳ thứ gì vào một tệp là trước tiên di chuyển nội dung cũ sang một vị trí mới bằng cách đọc nó từ vị trí cũ và ghi nó vào vị trí mới. Sau đó bạn có thể 'chèn' dữ liệu vào khu vực trống bây giờ.

4

Một vài tùy chọn khác:

file = File.read(path).sub(/line2\n/, 'Some nice little sentence\n\1') 
File.write(path, file) 

file = File.readlines(path) 
index = file.index("line2") 
file.insert(index, "Some nice little sentence") 
File.write(path, file) 
+0

Tôi đã cố gắng sử dụng điều này, nhưng 'File.write (đường dẫn, 'w')' ghi đè tập tin bằng ký tự đơn 'w' - cách tiếp cận chính xác là gì? – dgmstuart

7
def replace(filepath, regexp, *args, &block) 
    content = File.read(filepath).gsub(regexp, *args, &block) 
    File.open(filepath, 'wb') { |file| file.write(content) } 
end 


replace(my_file, /^line2/mi) { |match| "Some nice little sentence"} 

line1 
Some nice little sentence 
line2 
line3 
line4 

và nếu bạn muốn thêm đến hiện tại ...

replace(my_file, /^line2/mi) do |match| 
    "#{match} Some nice little sentence" 
end 

line1 
line2 Some nice little sentence 
line2 
line3 
line4 
+0

Tôi chắc rằng bạn đã nhận thấy rằng bạn đã in line2 hai lần trong ví dụ cuối cùng. – Magne

Các vấn đề liên quan