2013-06-15 7 views
3

Primer 3이라는 명령 줄 프로그램을 실행하고 있습니다. 입력 파일을 받아 데이터를 표준 출력으로 리턴합니다. 그 입력을 받아 들일 수있는 루비 스크립트를 작성하려고하고 있는데, 해시에 항목을 넣으려고합니다.복잡한 파일을 해시로 분할

결과는 다음과 같습니다.

{:SEQUENCE_ID => "example", :SEQUENCE_TEMPLATE => "GTAGTCAGTAGACNAT..etc", :SEQUENCE_TARGET => "37,21" etc } 

내가 또한 경우 키를 낮추기 위해 싶습니다 예 :

{:sequence_id => "example", :sequence_template => "GTAGTCAGTAGACNAT..etc", :sequence_target => "37,21" etc } 

이 나는이 것 같은 것을 가지고 있도록 '='기호의 데이터를 분할하고 싶습니다 내 현재 스크립트입니다 :

Primer 3 hash 
{"SEQUENCE_ID"=>0, "SEQUENCE_TEMPLATE"=>0, "SEQUENCE_TARGET"=>37, "PRIMER_TASK"=>0,  "PRIMER_PICK_LEFT_PRIMER"=>1, "PRIMER_PICK_INTERNAL_OLIGO"=>1, "PRIMER_PICK_RIGHT_PRIMER"=>1, "PRIMER_OPT_SIZE"=>18, "PRIMER_MIN_SIZE"=>15, "PRIMER_MAX_SIZE"=>21, "PRIMER_MAX_NS_ACCEPTED"=>1, "PRIMER_PRODUCT_SIZE_RANGE"=>75, "P3_FILE_FLAG"=>1, "SEQUENCE_INTERNAL_EXCLUDED_REGION"=>37, "PRIMER_EXPLAIN_FLAG"=>1, "PRIMER_THERMODYNAMIC_PARAMETERS_PATH"=>0, "PRIMER_LEFT_EXPLAIN"=>0, "PRIMER_RIGHT_EXPLAIN"=>0, "PRIMER_INTERNAL_EXPLAIN"=>0, "PRIMER_PAIR_EXPLAIN"=>0, "PRIMER_LEFT_NUM_RETURNED"=>0, "PRIMER_RIGHT_NUM_RETURNED"=>0, "PRIMER_INTERNAL_NUM_RETURNED"=>0, "PRIMER_PAIR_NUM_RETURNED"=>0, ""=>0} 
:

#!/usr/bin/ruby 
puts 'Primer 3 hash' 

primer3 = {} 
while line = gets do 
    name, height = line.split(/\=/) 
    primer3[name] = height.to_i 
end 

puts primer3 

그것은이를 반환

데이터 소스는

SEQUENCE_ID=example 
SEQUENCE_TEMPLATE=GTAGTCAGTAGACNATGACNACTGACGATGCAGACNACACACACACACACAGCACACAGGTATTAGTGGGCCATTCGATCCCGACCCAAATCGATAGCTACGATGACG 
SEQUENCE_TARGET=37,21 
PRIMER_TASK=pick_detection_primers 
PRIMER_PICK_LEFT_PRIMER=1 
PRIMER_PICK_INTERNAL_OLIGO=1 
PRIMER_PICK_RIGHT_PRIMER=1 
PRIMER_OPT_SIZE=18 
PRIMER_MIN_SIZE=15 
PRIMER_MAX_SIZE=21 
PRIMER_MAX_NS_ACCEPTED=1 
PRIMER_PRODUCT_SIZE_RANGE=75-100 
P3_FILE_FLAG=1 
SEQUENCE_INTERNAL_EXCLUDED_REGION=37,21 
PRIMER_EXPLAIN_FLAG=1 
PRIMER_THERMODYNAMIC_PARAMETERS_PATH=/usr/local/Cellar/primer3/2.3.4/bin/primer3_config/ 
PRIMER_LEFT_EXPLAIN=considered 65, too many Ns 17, low tm 48, ok 0 
PRIMER_RIGHT_EXPLAIN=considered 228, low tm 159, high tm 12, high hairpin stability 22, ok 35 
PRIMER_INTERNAL_EXPLAIN=considered 0, ok 0 
PRIMER_PAIR_EXPLAIN=considered 0, ok 0 
PRIMER_LEFT_NUM_RETURNED=0 
PRIMER_RIGHT_NUM_RETURNED=0 
PRIMER_INTERNAL_NUM_RETURNED=0 
PRIMER_PAIR_NUM_RETURNED=0 
= 

$ primer3_core < example2 | ruby /Users/sean/Dropbox/bin/rb/read_primer3.rb 
+1

+1 당신이 이미 시도한 것을 포함하여, 완벽한 형식의 완전한 질문입니다. – Phrogz

답변

4
#!/usr/bin/ruby 
puts 'Primer 3 hash' 

primer3 = {} 
while line = gets do 
    key, value = line.split(/=/, 2) 
    primer3[key.downcase.to_sym] = value.chomp 
end 

puts primer3 
+0

예, 완벽합니다. 감사. – ardochhigh

+0

@SeanGeneva 여러분을 환영합니다. –

+0

하나의 질문 : 무엇입니까, 2 여기 : 선.split (/ = /, 2) – ardochhigh

-1

OK 나는 그것을 (거의)이있다. 유일한 문제는 각 값의 끝에 \ n을 추가하는 것입니다.

puts 'Primer 3 hash' 

primer3 = {} 
while line = gets do 
    key, value = line.split(/\=/) 
    puts key 
    puts value 
    primer3[key.downcase] = value 
end 

puts primer3 

{"sequence_id"=>"example\n", "sequence_template"=>"GTAGTCAGTAGACNATGACNACTGACGATGCAGACNACACACACACACACAGCACACAGGTATTAGTGGGCCATTCGATCCCGACCCAAATCGATAGCTACGATGACG\n", "sequence_target"=>"37,21\n", "primer_task"=>"pick_detection_primers\n", "primer_pick_left_primer"=>"1\n", "primer_pick_internal_oligo"=>"1\n", "primer_pick_right_primer"=>"1\n", "primer_opt_size"=>"18\n", "primer_min_size"=>"15\n", "primer_max_size"=>"21\n", "primer_max_ns_accepted"=>"1\n", "primer_product_size_range"=>"75-100\n", "p3_file_flag"=>"1\n", "sequence_internal_excluded_region"=>"37,21\n", "primer_explain_flag"=>"1\n", "primer_thermodynamic_parameters_path"=>"/usr/local/Cellar/primer3/2.3.4/bin/primer3_config/\n", "primer_left_explain"=>"considered 65, too many Ns 17, low tm 48, ok 0\n", "primer_right_explain"=>"considered 228, low tm 159, high tm 12, high hairpin stability 22, ok 35\n", "primer_internal_explain"=>"considered 0, ok 0\n", "primer_pair_explain"=>"considered 0, ok 0\n", "primer_left_num_returned"=>"0\n", "primer_right_num_returned"=>"0\n", "primer_internal_num_returned"=>"0\n", "primer_pair_num_returned"=>"0\n", ""=>"\n"} 
+1

'.chomp'를 값에 추가하여 개행을 제거하십시오. – whirlwin

+0

왜 downvote? 다른 답변보다 먼저 게시되었습니다. – ardochhigh

+0

@SeanGeneva 나는 downvote하지 않았다. 그러나 질문 기준과 완전히 일치하지 않는 대답은 자주 downvoted이다. 예를 들어,이 대답은 파일 대신에'gets'를 사용하고 심볼 대신 키를 사용합니다. – Phrogz

4

재미를 들어, 여기에 순수하게 기능적인 솔루션의 몇 가지 있습니다. 둘 다 이미 파일에서 데이터를 가져온 것으로 가정합니다.

my_data = ARGF.read # read the file passed on the command line 

이 사람은 총의 종류를 느낀다, 그러나 그것은 (긴) 한 줄 :)

hash = Hash[ my_data.lines.map{ |line| 
    line.chomp.split('=',2).map.with_index{ |s,i| i==0 ? s.downcase.to_sym : s } 
} ] 

이 하나가 두 줄,하지만 with_index를 사용하는 것보다 깨끗한 느낌입니다 :

keys,values = my_data.lines.map{ |line| line.chomp.split('=',2) }.transpose 
hash = Hash[ keys.map(&:downcase).map(&:to_sym).zip(values) ] 

둘 다 덜 능률적이고 확실하게 이미 받아 들인 답변보다 메모리 집약적입니다. 선을 반복하고 천천히 해시를 돌연변이시키는 것이 최선의 방법입니다. 이러한 돌연변이가없는 변이는 정신 운동 일뿐입니다.


귀하의 최종 답변은 명령 줄이나 STDIN을 통해 파일 이름을 허용하는 ARGF을 사용해야합니다. 그래서처럼 작성합니다

#!/usr/bin/ruby 

module Primer3 
    def self.parse(file) 
    {}.tap do |primer3| 
     # Process one line at a time, without reading it all into memory first 
     file.each_line do |line| 
     key, value = line.chomp.split('=', 2) 
     primer3[key.downcase.to_sym] = value 
     end 
    end 
    end 
end 

Primer3.parse(ARGF) if __FILE__==$0 

이 방법 당신은 또는 STDIN하지 않고, 명령 줄에서 파일을 호출 할 수 있습니다, 또는 당신이 파일을 require하고 다른 코드에서 정의하는 모듈 기능을 사용할 수 있습니다.

+0

환상적인 답변입니다. 고마워요! – ardochhigh

관련 문제