tags:

views:

67

answers:

4

I have a sample position file like below.

789754654     COLORA         SOMETHING1     19370119FYY076    2342423234SS323423
742784897     COLORB        SOMETHING2      20060722FYY076    2342342342SDFSD3423

I am interested in positions 54-61 (4th column). I want to change the date to be a different format. So final outcome will be:

789754654     COLORA         SOMETHING1     01191937FYY076    2342423234SS323423
742784897     COLORB        SOMETHING2      07222006FYY076    2342342342SDFSD3423

The columns are seperated by spaces not tabs. And the final file should have exact number of spaces as the original file....only thing changing should be the date format. How can I do this? I wrote a script but it will lose the original spaces and positioning will be messed up.

file.each_line do |line|
 dob = line.split(" ")
 puts dob[3] #got the date. change its format
 5.times {  puts "**" }
end

Can anyone suggest a better strategy so that positioning in the original file remains the same?

A: 

I would:

  • Read the file in
  • Split the lines like you have
  • Store the data in an array (temporarily)
  • Do all the date changes, etc. you want to that array
  • Make a method that knows how to output your data correctly (with spaces) to turn the array back into a string
  • Print out what that method gives you

Take a look at String#ljust and/or String#rjust for making the conversion method.

Benjamin Oakes
+2  A: 

You can use line[range] to replace part of a line, leaving the rest the same.

#!/usr/bin/ruby1.8

line = "789754654     COLORA         SOMETHING1     19370119FYY076    2342423234SS323423"
line[44..57] = "01191937FYY076"
p line
# => "789754654     COLORA         SOMETHING1     01191937FYY076    2342423234SS323423"
Wayne Conrad
A: 

You can use String#sub for a simple search/replace.

>> s.sub(/(\d{8}FYY\d{3})(\s*)/){ "Original: '#$1', Spaces: '#$2'" }
=> "789754654     COLORA         SOMETHING1     Original: '19370119FYY076', Spaces: '    '2342423234SS323423"

Of course, in your case you'd output the reformatted date.

>> s.sub(/(\d{8}FYY\d{3})/){ $1.reverse }
=> "789754654     COLORA         SOMETHING1     670YYF91107391    2342423234SS323423"
manveru
A: 

Use a regex to break the line out into it's constituent parts, then put them back together in the order you require.

lines = [
'789754654     COLORA         SOMETHING1     19370119FYY076    2342423234SS323423',
'742784897     COLORB        SOMETHING2      20060722FYY076    2342342342SDFSD3423'  
]

rx = Regexp.new(/^(\d{9})(\s+)(\S+)(\s+)(\S+)(\s+)(\d{4})(\d{2})(\d{2})(FYY076)(\s+)(\S+)$/)
lines.each do |line|
    match = rx.match(line)      
    puts sprintf("%s%s%s%s%s%s%s%s%s%s%s%s",
        match[1], match[2], match[3], match[4], match[5], match[6],
        match[8], match[9], match[7], match[10],match[11],match[12]  
        )
end           

stephenr