简体   繁体   中英

Reading lines from a file and condensing them together

I have a file that I'm reading from that has this information in it:

  Organization: QC
  Company: Luxury Mortgage Corp. (0020)
  Folio: 3366326
  Doc Code: QCMAIL_STMT         
  Sequence: 3
  Pages: 7
  Method: SCAN            
  User: LAS             
  Received: 01/20/2016

I'm trying to pull the lines from the file and only use the Folio , Sequence , Pages and User .

However when I do this, it shows up like this:

Folio: 
Sequence: 
Page: 
User: 
Folio: 
Sequence: 
Page: 
User: 
Folio: 
Sequence: 
Page: 
User: 
Folio: 
Sequence: 
Page: 
User: 
Folio: 3366326
Sequence: 
Page: 
User: 
Folio: 
Sequence: 
Page: 
User: 
Folio: 
Sequence: 3
Page: 
User: 
Folio: 
Sequence: 
Page: 7
User: 
Folio: 
Sequence: 
Page: 
User: 
Folio: 
Sequence: 
Page: 
User: LAS

What I need is for it to show up likes this:

Folio: 3366326
Sequence: 3
Page: 7
User: LAS

Source:

#!/usr/local/bin/ruby

require 'colored'

class UncommittedDocs

  #attr_accessor :file

 # def initialize(username)
  #  @file = file
 # end

  def pull_info
    File.open("/home/qc/tep/bin/ruby/uncomitted.txt", "r").each_line do |line|
      puts "Folio: #{line.split(" ")[1] if line.include?("Folio")}"
      puts "Sequence: #{line.split(" ")[1] if line.include?("Sequence")}"
      puts "Page: #{line.split(" ")[1] if line.include?("Pages")}"
      puts "User: #{line.split(" ")[1] if line.include?("User")}"
    end
  end
end

test = UncommittedDocs.new#"/home/qc/tep/bin/ruby/uncommittedddocstest.txt")
test.pull_info

Your condition is misplaced.

Use this:

puts "Folio: #{line.split(" ")[1] if line.include?("Folio")}"

Instead of this:

puts "Folio: #{line.split(" ")[1]}" if line.include?("Folio")

It seems like you're doing a lot of work with line.split , etc., when you really just want to print lines that match certain criteria and skip the rest:

class UncommittedDocs
  MATCH_LINE_EXPR = /^(Folio|Sequence|Page|User):/

  def pull_info
    File.open("/home/qc/tep/bin/ruby/uncomitted.txt", "r").each_line do |line|
      puts line if line =~ MATCH_LINE_EXPR
    end
  end
end

test = UncommittedDocs.new
test.pull_info

If there is leading whitespace that you want to strip, then the following changes would accommodate that:

MATCH_LINE_EXPR = /^\s*(Folio|Sequence|Page|User):/

def pull_info
  File.open("/home/qc/tep/bin/ruby/uncomitted.txt", "r").each_line do |line|
    puts line.lstrip if line =~ MATCH_LINE_EXPR
  end
end

This just adds \\s* at the beginning of the regular expression (to match zero or more leading whitespace characters) and changes puts line to puts line.lstrip to strip any leading whitespace from matching lines.

To add a blank line after the User: line, per your comment, add another puts that will be executed only in that case. Since we're already capturing Folio|Sequence|Page|User in capture group 1, this is as simple as:

def pull_info
  File.open("/home/qc/tep/bin/ruby/uncomitted.txt", "r").each_line do |line|
    puts line if line =~ MATCH_LINE_EXPR
    puts if $1 == "User"
  end
end

Move the if s out of your string interpolations, so that it applies to the puts calls:

puts "Folio: #{line.split(" ")[1]}" if line.include?("Folio")

and you should be fine. That is, until you encounter data that contains your keywords, eg

  User: Mr. Folio Pages

To avoid that problem, use a stricter condition. The better you know the file's format, the better you can tailor it. If you don't have any specification but only the above example file content to work with, obt for something that's still robust like

puts "Folio: #{line.split(" ")[1]}" if line.strip.start_with?("Folio:")

If your input file is YAML (it looks like it might be), use Ruby's built-in YAML support :

require 'yaml'
require 'active_support/core_ext/hash/slice'  # For comfortably dissecting a Hash
                                 # See https://stackoverflow.com/a/25206082/674064

# ...

  def pull_info
    data = YAML.load_file('/home/qc/tep/bin/ruby/uncomitted.txt')
    puts data.slice('Folio', 'Sequence', 'Pages', 'User').to_yaml
  end

# ...
IO.foreach('/path/to/file.txt') { |l| puts l if l =~ /[Folio|Sequence|Pages|User]: \w/ }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM