2017-05-11 1 views
0

줄 단위로 파일 (d : \ mywork \ list.txt)을 읽고 해당 문자열이 특정 파일에서 (하나씩) 발생하는지 검색하려고합니다. 디렉토리 (d : \ new_work).여러 파일에서 줄을 지우는 방법

하나 이상의 파일에있는 경우 해당 파일에서 문자열 (car \ yrui3,)을 삭제하고 해당 파일을 저장하려고합니다.

List.txt 파일 :

car\yrui3, 
dom\09iuo, 
id\byt65_d, 
rfc\some_one, 
desk\aa_tyt_99, 
......... 
......... 

디렉토리 가진 여러 개의 파일 : D : new_work \를 :

Rollcar-access.txt 
Mycar-access.txt 
Newcar-access.txt 
....... 
...... 

내 코드 : 값이 점점되지 않습니다

value=File.open('D:\\mywork\\list.txt').read 
value.gsub!(/\r\n?/, "\n") 
value.each_line do |line| 
    line.chomp! 
    print "For the string: #{line}" 
    Dir.glob("D:/new_work/*-access.txt") do |fn| 
     print "checking files:#{fn}\n" 
     text = File.read(fn) 
     replace = text.gsub(line.strip, "") 
     File.open(fn, "w") { |file| file.puts replace } 
    end 
end 

문제입니다 예상대로 삭제되었습니다. 또한 text 값을 인쇄하려고 할 때 비어 있습니다.

+1

우리는 당신이 새로운 사람이든 경험이 많은 사람이든 관심이 없습니다. 우리는 잘 연구되고, 잘 질문하고 간결한 질문을 원합니다. 나는 "[똑똑한 방법으로 질문하는 법] (http://catb.org/esr/faqs/smart-questions.html)"을 읽는 것이 좋습니다. SO와 같은 커뮤니티와의 협력을 설명합니다. –

+0

귀하의 작업은 다소 "[XY 문제] (https://meta.stackexchange.com/q/66377/153968)"입니다. 당신은 당신의 구현에 대해 물어볼 것입니다. 문제를 다시 생각해 보는 것이 좋습니다. 파일은 무엇을 나타 냅니까? 왜 데이터가 여러 파일에 분산되어 있습니까? 신속하게 검색하고 삭제할 수있는 파일 내용을 저장하기 위해 데이터베이스 사용을 고려하십시오. SQLite조차도이 작업을 신속하게 처리 할 수 ​​있으며 Sequel, Datamapper 또는 Active Record와 같은 ORM을 사용하여 매우 쉽게 수행 할 수 있습니다. –

답변

2

코드에 여러 가지 문제가 있으며 파일 변경 사항을 안전하게 처리하지 못합니다. 이 테스트되지 않은 코드에

묵상 : 당신의 코드에서

ACCESS_FILES = Dir.glob("D:/new_work/*-access.txt") 

File.foreach('D:/mywork/list.txt') do |target| 
    target = target.strip.sub(/,$/, '') 

    ACCESS_FILES.each do |filename| 
    new_filename = "#{filename}.new" 
    old_filename = "#{filename}.old" 

    File.open(new_filename, 'w') do |fileout| 
     File.foreach(filename) do |line_in| 
     fileout.puts line_in unless line_in[target] 
     end 
    end 

    File.rename(filename, old_filename) 
    File.rename(new_filename, filename) 
    File.delete(old_filename) 
    end 
end 
  • 당신이 사용

    File.open('D:\\mywork\\list.txt').read 
    

    대신, 짧은, 그리고 더 간결하고 명확한 방법은 사용하는 것입니다 :

    File.read('D:/mywork/list.txt') 
    

    루비는 자동으로 운영 체제에 따라 경로 이름 분리 기호를 조정해야하므로 항상 슬래시를 사용하여 가독성을 높이십시오. the IO documentation에서 :

루비는 다른 운영 체제의 규칙 가능한 경우 사이의 경로 이름을 변환합니다. 예를 들어, Windows 시스템에서 파일 이름 "/gumby/ruby/test.rb"은 "\gumby\ruby\test.rb"으로 열립니다.

read을 사용하는 문제는 확장 가능하지 않습니다. 장기 생산 시스템에서이 작업을 수행하고 입력 파일이 TB 범위로 증가한 경우를 상상해보십시오. 파일을 읽을 수있을 때까지 시스템에서 처리를 중단합니다. 그러지 마.

대신 foreach을 사용하여 줄 단위로 읽을 수 있습니다. "Why is "slurping" a file not a good practice?"을 참조하십시오.즉, 괜찮

value.gsub!(/\r\n?/, "\n") 
    value.each_line do |line| 
     line.chomp! 
  • Dir.glob("D:/new_work/*-access.txt") do |fn| 
    

    동안의 필요성을 제거하는 것, 그 배치는 없습니다. 파일을 처리 할 때마다 처리되는 모든 행에 대해 CPU를 낭비합니다. 먼저 읽은 다음 값을 저장 한 다음 해당 값을 반복적으로 반복합니다. 다시

  • ,

    text = File.read(fn) 
    

    는 확장 성 문제가 있습니다. foreach을 사용하는 것이 더 나은 해결책입니다. 다시.

  • gsub가 빠르고 사용하여 텍스트를 교체하지만, IO 그냥 빨리하고 완전하게 문제를 비켜 줄 단위로 할 때 확장 성의 잠재적 인 문제보다 중요하지 않습니다

    replace = text.gsub(line.strip, "") 
    
  • 열기 더 좋은 연습 무언가가에 이전 파일의 이름을 변경, 별도의 새로운 파일을 작성하는 것입니다

    File.open(fn, "w") { |file| file.puts replace } 
    

    : 당신이 읽는 한 것과 동일한 파일에 쓰기를하면 파일이 프로덕션 환경에서 발생하는 대기 사고입니다 그런 다음 새 파일의 이름을 이전 파일의 이름으로 바꿉니다. 이렇게하면 코드 또는 기계가 중간 저장에 실패 할 경우를 대비하여 이전 파일을 유지합니다. 그런 다음 작업이 끝나면 이전 파일을 제거하는 것이 안전합니다. 자세한 내용은 "How to search file text for a pattern and replace it with a given value"을 참조하십시오.

최종 권장 사항은 입력 파일에서 모든 쉼표를 제거하는 것입니다. 그들은 아무 것도 성취하지 못하고 단지 파일을 처리하기 위해 여분의 작업을하고 있습니다.

+0

@TinMan : 고마워, 분명히 당신이 제안한 모범 사례를 따를 것이다. – voltas

1

방금 ​​코드를 실행했고 내 컴퓨터에서 예상대로 작동합니다. 내 생각 엔 list.txt의 각 행 끝에 쉼표를 사용하지 않는 것이 좋습니다. 추가 chomp!로 제거하십시오 : 어쨌든 모든 줄 바꿈을 멀리 받기를 갈망하고 있기 때문에 value.gsub!(/\r\n?/, "\n"), 그리고 씹는는 기본적으로 \r\n을 인식 할 수 있습니다 :

value=File.open('D:\\mywork\\list.txt').read 
value.gsub!(/\r\n?/, "\n") 
value.each_line do |line| 
    line.chomp! 
    line.chomp!(",") 
    print "For the string: #{line}" 
    Dir.glob("D:/new_work/*-access.txt") do |fn| 
     print "checking files:#{fn}\n" 
     text = File.read(fn) 
     replace = text.gsub(line.strip, "") 
     File.open(fn, "w") { |file| file.puts replace } 
    end 
end 

을 그건 그렇고, 당신은이 줄을 필요가 없습니다.

+0

시간과 제안에 감사드립니다. 매우 감사. – voltas

관련 문제