Hello, I am completely new to Ruby and want to start learning it in an
efficient way. Can anyone create a text processing Ruby script for me? I
attached a perl script that shows that way I did it.
I need a ruby script to convert demo.txt to out.txt;
######### out.txt
--------- ENGINE --------
the DATA width is 15 in decimal
the ADDR width is 15 in decimal
the LENG width is 31 in decimal
the WIDT width is 60 in decimal
the THIC width is 1 in decimal
the FUSE status is NO
the SWIT status is DISABLED
I've pretty much left the Regexp alone, here's my translation:
File.write( 'out.txt', File.foreach('demo.txt').map do |line|
case line
when /\bBLOCK\s+(\w+)/
"--------- #{$1} --------"
when /(\w+)\s*:\s*(\d+) -- (\d+)/
"the %-10s width is %-5d in decimal" % [ $1[0..3], $2.to_i -
$3.to_i ]
when /(\w+)\s*:\s*(\w+)/
"the %-10s status is %-5s" % [ $1[0..3], $2 ]
end
end.compact.join($/) )
Output:
--------- ENGINE --------
the DATA width is 15 in decimal
the ADDR width is 15 in decimal
the LENG width is 31 in decimal
the WIDT width is 60 in decimal
the THIC width is 1 in decimal
the FUSE status is NO
the SWIT status is DISABLED
foreach my $line(@lines) {
if ($line =~ m/\bBLOCK\s+(\w+)/) {
printf "--------- %s --------\n", $1;
}
if ($line =~ m/(\w+)\s*:\s*(\d+) -- (\d+)/) {
my $w = substr ($1, 0, 4);
my $d = $2 - $3;
printf "the %-10s width is %-5d in decimal\n", $w, $d;
}
elsif ($line =~ m/(\w+)\s*:\s*(\w+)/) {
my $w = substr ($1, 0, 4);
printf "the %-10s status is %-5s\n", $w, $2;
}
}
Here is a way to keep the regular expression more readable (for me, anyway).
You may need some adjustments depending on your specs.
f = File.open("./out.txt","w")
File.open("./demo.txt","r").each do |x|
y = x.chomp.split(/BLOCK|:|--|;|END/)
f.puts "--------- #{y[1].lstrip} --------" if y.size==2 && y[0] == ""
f.puts "the #{y[0].lstrip[0..3]} width is
#{(y[1].to_i-y[2].to_i).to_s.ljust(2)} in decimal" if y.size==3
f.puts "the #{y[0].lstrip[0..3]} status is #{y[1].lstrip}" if
y.size==2 && y[0] != ""
f.puts if y.size==0
end
Thanks Harry, your solution is good for me. Your strategy is actually
convert the text into an array line by line, and then pick up what you
want to format. I learned much from your example.
Something that I don't understand is why you need add:
<quote> f.puts if y.size==0 </quote>
Are you going to print a new line?
Hello Robert, I like your recommended style; it will make the script
more reusable. As to output, I am OKAY to STDOUT or file_io, but this
might be my mistake which I showed in Perl with STDOUT but actually I
required file_io.
You can add it to 1.8 simply by defining it. Ruby 1.8.5/6 was released
almost seven years ago. It was a much different language then. Some of the
block scoping paradigms have changed. What's a more interesting is why
later rubies don't support legacy syntax as these "bugs" were fixed.
···
On Fri, Oct 4, 2013 at 6:04 PM, Dave Hwong <lists@ruby-forum.com> wrote:
Okay, when I moved to Ruby1.9.x the issue disappeared.
Here is a way to keep the regular expression more readable (for me, anyway).
Uh, your brain must have quite different wiring than mine.
You may need some adjustments depending on your specs.
f = File.open("./out.txt","w")
File.open("./demo.txt","r").each do |x|
y = x.chomp.split(/BLOCK|:|--|;|END/)
f.puts "--------- #{y[1].lstrip} --------" if y.size==2 && y[0] == ""
f.puts "the #{y[0].lstrip[0..3]} width is
#{(y[1].to_i-y[2].to_i).to_s.ljust(2)} in decimal" if y.size==3
f.puts "the #{y[0].lstrip[0..3]} status is #{y[1].lstrip}" if
y.size==2 && y[0] != ""
f.puts if y.size==0
end
You could at least have closed file handles properly.
I'd probably have taken Joel's solution with these small changes:
- use ARGF so users can post arbitrary number of files on command line
- output to stdout so user can decide where the output goes
ARGF.each_line do |line|
case line
when /\bBLOCK\s+(\w+)/
puts "--------- #$1 --------"
when /(\w+)\s*:\s*(\d+) -- (\d+)/
printf "the %-10s width is %-5d in decimal\n", $1[0, 4], $2.to_i - $3.to_i
when /(\w+)\s*:\s*(\w+)/
printf "the %-10s status is %-5s\n", $1[0, 4], $2
end
end
Kind regards
robert
···
On Sat, Oct 5, 2013 at 4:32 PM, Harry Kakueki <list.push@gmail.com> wrote:
> Here is a way to keep the regular expression more readable (for me,
anyway).
Uh, your brain must have quite different wiring than mine.
I'm sure it does. Thank you.
I'd probably have taken Joel's solution with these small changes:
- use ARGF so users can post arbitrary number of files on command line
- output to stdout so user can decide where the output goes
You are not the one asking for a solution.
I just offered an idea to the OP and I indicated that he may want to make
some changes.
What you want doesn't matter.
Have a nice day.
That line is not necessary.
It just puts a space between ENDBLOCK and the beginning of another block if
there is one.
Not important.
Harry
···
On Sun, Oct 6, 2013 at 7:26 AM, Dave Hwong <lists@ruby-forum.com> wrote:
Thanks Harry, your solution is good for me. Your strategy is actually
convert the text into an array line by line, and then pick up what you
want to format. I learned much from your example.
Something that I don't understand is why you need add:
<quote> f.puts if y.size==0 </quote>
Are you going to print a new line?
I sense there might be a misunderstanding: I did not intend to
depreciate anybody's brain wiring. I just wanted to stress the
obvious. And similarly to you I offered a solution which is subject
to commenting by anyone - as anyone else's is, too.
Cheers
robert
···
On Sat, Oct 5, 2013 at 5:39 PM, Harry Kakueki <list.push@gmail.com> wrote:
> Here is a way to keep the regular expression more readable (for me,
> anyway).
Uh, your brain must have quite different wiring than mine.
I'm sure it does. Thank you.
I'd probably have taken Joel's solution with these small changes:
- use ARGF so users can post arbitrary number of files on command line
- output to stdout so user can decide where the output goes
You are not the one asking for a solution.
I just offered an idea to the OP and I indicated that he may want to make
some changes.
What you want doesn't matter.
Have a nice day.
I sense there might be a misunderstanding: I did not intend to
depreciate anybody's brain wiring. I just wanted to stress the
obvious. And similarly to you I offered a solution which is subject
to commenting by anyone - as anyone else's is, too.
Maybe.
Maybe it is a cultural thing.
The brain wiring comment did not bother me.
Different does not mean bad.
The fact that you commented on my example did not bother me.
But,
"You forgot to close the file."
You could at least have closed file handles properly.
See any difference? I did.
Harry
···
On Sun, Oct 6, 2013 at 9:06 PM, Robert Klemme <shortcutter@googlemail.com>wrote:
On Sat, Oct 5, 2013 at 5:39 PM, Harry Kakueki <list.push@gmail.com> wrote:
I didn't as the offending quote was not included in your response.
But now I see where you're coming from. Thank you for the
explanation! That is a bad way to put it. I am sorry.
Kind regards
robert
···
On Sun, Oct 6, 2013 at 3:35 PM, Harry Kakueki <list.push@gmail.com> wrote:
On Sun, Oct 6, 2013 at 9:06 PM, Robert Klemme <shortcutter@googlemail.com> > wrote:
On Sat, Oct 5, 2013 at 5:39 PM, Harry Kakueki <list.push@gmail.com> wrote:
>
I sense there might be a misunderstanding: I did not intend to
depreciate anybody's brain wiring. I just wanted to stress the
obvious. And similarly to you I offered a solution which is subject
to commenting by anyone - as anyone else's is, too.
Maybe.
Maybe it is a cultural thing.
The brain wiring comment did not bother me.
Different does not mean bad.
The fact that you commented on my example did not bother me.
But,
"You forgot to close the file."
You could at least have closed file handles properly.
I didn't as the offending quote was not included in your response.
But now I see where you're coming from. Thank you for the
explanation! That is a bad way to put it. I am sorry.