Ruby: Put multiple lines from file - ruby

Right, so I have a file in which I want to get two different strings
text.txt:
abc
def
ghi
jkl
abc
ghi
How would I go about reading this and printing out two lines?
I'm currently here:
File.open(filename) do |f|
f.each_line do |line|
if line =~ /abc/
puts "Current things: #{line}"
end
end
end
I was thinking something like this (which obv doesn't work hence the question)
File.open(filename) do |f|
f.each_line do |line,line2|
if line =~ /abc/ and line2 =~ /ghi/
puts "Current things: #{line} #{line2}"
end
end
end
Am I WAY out on this one?
expected output:
Current things: abc ghi

An alternative, a bit shorter solution:
lines = File.foreach(filename, chomp: true).each_with_object([]) do |line, arr|
arr << line if line.match?(/abc|ghi/)
end
puts "Current things: #{lines.join(' ')}" if lines.any?
# => Current things: abc ghi abc ghi
If you want unique lines:
require 'set'
lines = File.foreach(filename, chomp: true).each_with_object(Set.new) do |line, set|
set.add(line) if line.match?(/abc|ghi/)
end
puts "Current things: #{lines.to_a.join(' ')}" if lines.any?
# => Current things: abc ghi

You could use an array to store the matching lines and then print them when finished iterating.
File.open(filename) do |f|
matching_lines = []
f.each_line do |line|
if line =~ /abc/ || line =~ /ghi/
matching_lines << line
end
end
puts "Current things: #{matching_lines.join(' ')}" unless matching_lines.empty?
end

Related

ruby How I could print without leave newline space for each line?

ruby How I could print without leave newline space for each line
this is my file
name1;name2;name3
name4;name5;name6
I have this command
File.open("text2xycff.txt", "r") do |fix|
fix.readlines.each do |line|
parts = line.chomp.split(';')
input3= zero
File.open('text2xyczzzz2.txt', 'a+') do |f|
f.puts parts[0] , parts[1], parts[2] ,input3
end
end
end
this is my output
name1
name2
name3
zero
name4
name5
name6
zero
I need to output this
name1;name2;name3;zero
name4;name5;name6;zero
Please help me whit this problem
A more minimal approach is to just append something to each line:
File.open("text2xycff.txt", "r") do |input|
File.open('text2xyczzzz2.txt', 'a+') do |output|
input.readlines.each do |line|
output.puts(line.chomp + ';zero')
end
end
end
Or if you want to actually parse things, which presents an opportunity for clean-up:
File.open("text2xycff.txt", "r") do |input|
File.open('text2xyczzzz2.txt', 'a+') do |output|
input.readlines.each do |line|
parts = line.chomp.split(/;/)
parts << 'zero'
output.puts(parts.join(';'))
end
end
end
You have two solutions.
The first one uses puts as you currently do:
File.open('yourfile.txt', 'a+') { |f|
f.puts "#{parts[0]}#{parts[1]}#{parts[2]}#{input3}"
}
The second one uses write instead of puts:
File.open('yourfile.txt', 'a+') { |f|
f.write parts[0]
f.write parts[1]
f.write parts[2]
f.write input3
}
If you call puts with comma-separated arguments, each one of them will be printed on a different line.
You can use ruby string interpolation here (http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html):
f.puts "#{parts[0]};#{parts[1]};#{parts[3]};#{input3}"
Try:
File.open("test_io.txt", "r") do |fix|
fix.readlines.each do |line|
File.open('new_file10.txt', 'a+') do |f|
next if line == "\n"
f.puts "#{line.chomp};zero"
end
end
end
I'm not sure why you're splitting the string by semicolon when you specified you wanted the below output. You would be better served just appending ";zero" to the end of the string rather than parsing an array.
name1;name2;name3;zero
name4;name5;name6;zero
You can specify an if statement to check for the zero value.
Example:
arr = ["name1", "name2", "name3", "zero", "name4", "name5", "name6", "zero"];
arr.each { |x|
if x != "zero" then
print x
else
puts x
end
}
Output:
name1name2name3zero
name4name5name6zero
print will print inline.
puts will print on a new line.
Just implement this logic in your code and you're good to go.

how i could wrapped two command in ruby?

Im trying to wrapped this two command in ruby but not work
ruby -a -ne 'print $F[0].gsub(/=(.*?)&/," \"\\1\" and ")' prueban > prueban2
ruby -a -F';' -ne 'puts $F[0].sub("less"," <")' prueban2 > prueban3
this is my command
File.open("text.txt", "r") do |fi|
fi.readlines.each do |line|
parts = line.chomp.split(';')
fx= puts parts[0].gsub(/=(.*?)&/," \"\\1\" and ")
end
fx.readlines.each do |line|
parts = line.chomp.split(';')
fx= puts parts[0].gsub("less"," <")
end
end
this is my file
pricegreater=2&priceless=4&seleccionequal=pet&
and this is my expected output
pricegreater "2" and price < "4" and seleccionequal "pet" and
I dont know whats is doing wrong please help me
Here's a reworked version of the core function to show how to do it in a more Ruby-esque way:
# Define a lookup table of all substitutions
REWRITE = {
'greater' => '>',
'less' => '<',
'equal' => '='
}
# Use the lookup table to create a regular expression that matches them all
REWRITE_RX = Regexp.new(Regexp.union(REWRITE.keys).to_s + '\z')
def rewrite(input)
# Split up each main part of the input on &
input.split('&').map do |pair|
# Carve up each part into a var and value on =
var, value = pair.split('=')
# Replace terms found in the lookup table
var.sub!(REWRITE_RX) do |m|
' ' + REWRITE[m]
end
# Combine these to get the result
[ var, value ].join(' ')
end.join(' and ')
end
Put into action you get this:
rewrite("pricegreater=2&priceless=4&seleccionequal=pet&")
# => "price > 2 and price < 4 and seleccion = pet"
I solved with this
File.open("text.txt", "r") do |fi|
fi.readlines.each do |line|
parts = line.chomp.split(';')
f = File.open('text2.txt', 'w')
old_out = $stdout
$stdout = f
puts parts[0].gsub(/=(.*?)&/," \"\\1\" and ")
f.close
$stdout = old_out
end
end
File.open("text2.txt", "r") do |fi|
fi.readlines.each do |line|
parts = line.chomp.split(';')
f = File.open('text3.txt', 'w')
old_out = $stdout
$stdout = f
puts parts[0].sub("less"," <")
f.close
$stdout = old_out
end
end

How to append a new line write to a file with ruby?

My code is:
def write_to_file(line, my_file)
File.open(my_file, 'a') do |file|
p '-----loop number:' + line.id.to_s
file.puts "#{line.id}"
end
end
If I loop three times with this method, I can see:
-----loop number:1
-----loop number:2
-----loop number:3
But it can only write the last id into my_file. Even I tried:
file << "#{line.id}"
# or
file.write "#{line.id}\n"
The result was the same.
try this
def write_to_file(line, my_file)
File.open(my_file, 'a') do |file|
p '-----loop number:' + line.to_s
file.puts "#{line}"
end
end
[1,2,3,4].each do |line|
write_to_file(line, my_file)
end

What is wrong with my if statements?

Working in Ruby, I'm trying to make it so when I enter a line of input it'll read it and match it with a few if statements.
input_stream = $stdin
input_stream.each_line do |line|
puts line
if line == "a"
puts "test 1"
end
if line == "b"
puts "test 2"
end
end
But when I run it, and enter in "a" or "b", this is the output
a
a
b
b
It recognizes that I entered a and b, and prints it back to me, but the if statements don't function as expected. What is the problem here?
Ruby maintains the newline when using each_line. The simplest solution is to drop it with chomp.
input_stream = $stdin
input_stream.each_line do |line|
line.chomp! # The new helpful line
puts line
if line == "a"
puts "test 1"
end
if line == "b"
puts "test 2"
end
end
Because line has \n character at the end if you write this it will work:
input_stream = $stdin
input_stream.each_line do |line|
puts line
if line.chomp == "a"
puts "test 1"
end
if line.chomp == "b"
puts "test 2"
end
end

Trying to compare two text files, and create a third based on information

I have two text files, master.txt and 926.txt. If there is a line in 926.txt that is not in master.txt, I want to write to a new file, notinbook.txt.
I wrote the best thing I could think of, but given that I'm a terrible/newbie programmer it failed. Here's what I have
g = File.new("notinbook.txt", "w")
File.open("926.txt", "r") do |f|
while (line = f.gets)
x = line.chomp
if
File.open("master.txt","w") do |h|
end
while (line = h.gets)
if line.chomp != x
puts line
end
end
end
end
end
g.close
Of course, it fails. Thanks!
This should work:
f1 = IO.readlines("926.txt").map(&:chomp)
f2 = IO.readlines("master.txt").map(&:chomp)
File.open("notinbook.txt","w"){ |f| f.write((f1-f2).join("\n")) }
This was my test:
926.txt
line1
line2
line3
line4
line5
master.txt
line1
line2
line4
notinbook.txt
line3
line5
You can do something like this:
master_lines = []
File.open("notinbook.txt","w") do |result|
File.open("master.txt","r") do |master|
master.each_line do |line|
master_lines << line.chomp
end
end
File.open("926.txt","r") do |query|
query.each_line do |line|
if !master_lines.include? line.chomp
result.puts line.chomp
end
end
end
end
Use : http://raa.ruby-lang.org/project/compare/
OR
%x(diff file1 file2)
OR
http://github.com/myobie/htmldiff/
Hope this helps
dir = File.dirname(__FILE__)
notinbook = "#{dir}/notinbook.txt"
master = "#{dir}/master.txt"
f926 = "#{dir}/926.txt"
def file_into_ary(file)
ary = []
File.open(file).each{ |line| ary << line }
return ary
end
def write_difference(file, diff)
File.open(file, 'w') do |file|
diff.each do |line|
file.write(line)
end
end
end
diff = file_into_ary(f926) - file_into_ary(master)
write_difference(notinbook, diff) unless diff.empty?

Resources