【问题标题】:Extract text from a file and save the results into a pipe-delimited file从文件中提取文本并将结果保存到以竖线分隔的文件中
【发布时间】:2012-02-19 01:59:50
【问题描述】:

我不是程序员,但我正在学习生物信息学课程,因为我是分子遗传学专业的......我们的任务是获取一个包含多个条目的文件,如下所示:

77:XP_001929585
预测:类似于 BRCA1 相关蛋白 [Sus scrofa] gi|194042959|ref|XP_001929585.1| [194042959]

并提取我加粗的项目,然后将结果保存到管道分隔的文件中,如下所示:

194042959|Sus scrofa|PREDICTED: similar to BRCA1 associated protein.

我们正在使用 Sublime 编辑器在 Ruby 中编写我们的脚本。我知道如何打开文件,然后......好吧,这是我的脚本到目前为止......

#!/usr/local/bin/ruby
File.open("mmg231_hw5_brca1.txt").each do |file_line|
  if file_line =~ /^(.+)\[([A-Z].+)\]/
    description = $1
    taxon_name = $2
    puts "#{taxon_name}|#{description}" 
  elsif file_line =~ /\[([0-9].+)\]/
    gi_number = $1
    puts "#{gi_number}"
  end
end

我知道这是错误的......正则表达式确实捕获了他们需要的内容。第一个 puts 确实正确地列出了分类单元名称和描述,但我不知道如何在其中获取 gi 号,因为它在不同的行上......我可以自己拉出 gi 号也,但无法将其链接到其他两个部分。此外,当我使用我开发的正则表达式将它们拉出时,它们保持在文件中的正确顺序,所以我试图想办法告诉计算机为每个分类单元名称/描述对编号 1 , 2, 3, etc as in the file, 然后对 gi 号做同样的事情,然后你可以说分类单元名称/描述 1 与 gi 号 1 等... 或者让计算机获取分类单元名称和描述对,然后在下一行中查找 gi 号,但我不知道该怎么做......

帮助?用简单的英语会很有帮助,我觉得我可以使用大多数帮助网站,但我就是不懂这种语言......

前 4 个条目:

1: ZP_00239925
BRCA1 [Bacillus cereus G9241]
gi|47569239|ref|ZP_00239925.1||gnl|WGS:NZ_AAEK|BCE_G9241_3679 [47569239]

2: NP_009225
breast cancer 1, early onset isoform 1 [Homo sapiens]
gi|6552299|ref|NP_009225.1| [6552299]

3: NP_033894
breast cancer 1 [Mus musculus]
gi|161016835|ref|NP_033894.3| [161016835]

4: NP_036646
breast cancer 1 [Rattus norvegicus]
gi|6978573|ref|NP_036646.1| [6978573]

【问题讨论】:

  • 我认为如果您显示更多输入文件示例会有所帮助。
  • 您能否发布mmg231_hw5_brca1.txt 的示例,其中包含3 个不同的条目?您的输入文件有多大(以 MB 为单位)以及将来可能使用多大的文件作为输入?
  • 我添加了前 4 个条目 - 其中有 4328 个...

标签: ruby regex


【解决方案1】:

线条总是成对出现吗?

如果是这样,为什么不这样做:

description = taxon_name = gi_number = nil
first = false
File.open("mmg231_hw5_brca1.txt").each do |file_line|

  if file_line =~ /^(.+)\[([A-Z].+)\]/    
    description = $1
    taxon_name = $2
    first = true #Just to check they are consecutive 
  else
    if file_line =~ /\[([0-9].+)\]/
      gi_number = $1
      if first == true
        puts "#{gi_number}|#{taxon_name}|#{description}"
      end
    end
    first = false
  end
end

【讨论】:

  • 太棒了!非常感谢!如果问的不多,你能解释一下你所做的背后的逻辑吗?
  • 您面临的问题是文件的一行中有部分数据,而下一行中有部分数据。所以,我所做的就是保留第一行的 descriptio 和 taxon_name,添加一个布尔变量来指示第一行已被读取。然后循环读取另一行,我检查它是否匹配第一行,它不会,如果它匹配第二行,我得到 gi_number 并打印所有数据。
【解决方案2】:

你的意思是这样的?

http://ideone.com/MGW3Z

description, taxon_name = nil, nil

STDIN.each do |line|
  case line
  when /^(.+?\: .+) \[(.+?)\]$/
    description, taxon_name = $1, $2
  when /^.+?\|(\d+)\|\w+\|/
    gi_number = $1
    puts "#{gi_number}|#{taxon_name}|#{description}."
  end
end

我猜,如果您希望准确并检查“XP_001929585”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 2021-12-24
    相关资源
    最近更新 更多