2012-07-14 4 views
4

평평한 .txt 파일에 데이터 청크를 저장하는 스크립트를 작성하려고합니다. (파일 크기가 100 줄 미만)입니다.텍스트 파일에서 일치하는 한 줄을 어떻게 업데이트합니까?

어쨌든, 나는 그 라인의 새로운 값으로 하나의 매치 라인을 갱신하려고 노력하고 있지만, 그 라인의 모든 것을 홀로 남겨 두지 만, 그 라인을 대체하는 대신 단지 한 라인 만 수정하는 방법을 알 수는 없다. 전체 파일. textfile.txt 내용은 항상 형식으로 구성됩니다

# get file contents as array. 
array_of_lines = File.open("textfile.txt", "r").readlines.map(&:chomp) 

line_start = "123456:" # unique identifier 
new_string = "somestring" # a new string to be put after the line_start indentifier. 

# cycle through array finding the one to be updated/replaced with a new line. 
# the line we're looking for is in format 123456:some old value 

# delete the line matching the line_start key 
array_of_lines.delete_if(|line| line_start =~ line) 

# write new string into the array. 
array_of_lines.push("#{line_start}:#{new_string}") 

# write array contents back to file, replacing all previous content in the process 
File.open("textfile.txt", "w") do |f| 
    array_of_lines.each do |line| 
     f.puts line 
    end 
end 

:

UNIQUE_ID : string_of_text

나는 unique_id을 일치시킬 수 있습니다 여기에

지금까지 내 코드입니다 스크립트로 생성 된 앱 데이터를 사용하여 업데이트 할 텍스트 행을 찾습니다.

내가하는 일을하는 더 좋은 방법이 있습니까?

전체 파일을 메모리로 읽어 들여 모든 파일을 반복하여 파일의 한 줄만 업데이트하면 약간 비효율적 인 것처럼 보입니다.

+1

참고 사항 : http://stackoverflow.com/questions/4397412/read-edit-and-write-a-text-file-line-wise-using-ruby/4399299#4399299 –

+0

감사합니다 웨인, 알아두면 좋음 잠재적 인 성능/메모리 문제에 대해 – Jannis

+0

파일을 메모리에 저장하지 않는다면'readlines'를 사용하지 마십시오. 스크립트의 사용 가능한 메모리보다 크면 처리가 크롤링됩니다. 대신'foreach' 또는'each_line'을 사용하여 파일을 줄 단위로 읽으십시오. 더 빠르고 확장 성이 뛰어납니다. http://stackoverflow.com/a/25189286/128421 –

답변

4

작성중인 새 데이터의 길이가 이전 데이터와 같지 않으면 원하는 것을 수행 할 수 없습니다.

길이가 다른 경우 수정 후 파일의 모든 바이트를 이동해야합니다. 파일 데이터를 이동하면 모든 사항을 다시 작성해야합니다 (수정 시점부터). 이 경우 파일이 너무 작기 때문에 전체 파일을 다시 작성할 수도 있습니다.

대체 데이터가 동일한 경우 IO.seek을 사용하여 파일 포인터를 적절한 위치에 놓은 다음 write을 사용하여 대체 데이터를 입력 할 수 있습니다.

그래도 전체 파일을 다시 쓰지 않고 (대체 길이가 다른 경우) 데이터를 이동하려는 경우 올바른 위치에 seek이 필요하고 그 다음에 write이 끝납니다. 그 시점부터 파일. 교체가 더 짧으면 File.truncate으로 전화하여 파일의 크기를 조정해야합니다.

+0

답변 해 주셔서 감사합니다. Ruby를 처음 접한 이래로 저는 여기서 옳은 길을 가고 있다는 것을 알고 있습니다. 파일 재 작성에 관한 한 가지 질문 :'array_of_lines'를'array_of_lines.join ("\ n")'을 통해 먼저 하나의 문자열로 연결 한 다음이 파일을 한 번만 작성하거나 필자는 각 루프를 각 루프 내에서 파일에 쓰는 것이 좋았습니다. – Jannis

+0

@ Jannis - 어느 쪽이 더 효율적인지 말하는 것은 어렵습니다. 나는 당신이하는 것처럼 그들을 따로 씁니다. 결합하면 메모리에 하나 이상의 임시 문자열이 만들어집니다. 그러나 ** 최선의 선택 **은 전체 배열을 가지고'puts'를 호출 할 수 있다는 것을 깨닫는 것입니다 :'f.puts array_of_lines'. 루프하거나 조인 할 필요가 없습니다. – Casper

+0

또한 원하는 것을 수행하는 하나의 라이너에 대해 살펴볼 수도 있습니다. http://stackoverflow.com/questions/1274605/ruby-search-file-text-for-a-pattern-and-replace -it-with-a-given-value – Casper

관련 문제