How to multiply each number in a text file by 10 - ruby

I've been working on this for a while
But whatever I try it modifies only the first line, while I want to multioly each number by 10.
For example:
1
2
3.3
4.5
.
.
.
Should be:
10
20
33
45
But what I'm getting is :
10.0
Only
I've brought this from a stackoverflow question, and modified it but still the same result:
f = File.open("c:/Ruby/m.txt", "r+")
f.each_line do |line|
f.write( line.to_f * 10)
end
f.close
if I try to use f.puts I would get an error: puts is a private method? How can I multiply each number by 10?

I think you'd be better off reading the file first, and only then writing to it:
lines = File.readlines("c:/Ruby/m.txt").to_a
f = File.open("c:/Ruby/m.txt", "w")
lines.each do |line|
f.write((line.to_f * 10).to_i)
end
f.close

lines = File.readlines("c:/Ruby/m.txt")
new_lines = lines.map { |line| (line.to_f * 10).to_i }
File.open("c:/Ruby/m.txt", "w") { |f| f.puts new_lines }

Related

Writing regex result into a new file

I've got a list of devices:
ipc-bei640-r-br-01
ipc-bei640-r-br-02
ipc-bei640-r-br-03
ipc-bei640-r-br-04
ipc-bei640-r-br-05
ipc-bem640-r-br-01
ipc-bem640-r-br-02
ipc-bem640-r-br-03
ipc-crg660-r-br-02
ipc-geb680-r-br-04
ipc-lgv630-r-br-01
This small little ruby script counts the lines of the file braslist.txt scans it with a regex and writes the results to a newfile called "strippedfile.txt"
lines = IO.readlines("/usr/local/bin/braslist.txt")
# Linecount is forwarded to StdOut.
puts lines.length
str = File.read('braslist.txt')
file_name = ['strippedfile.txt']
file_name.each do |file_name|
text = File.read(file_name)
new_contents = str.scan(/^ipc-(?<bng>[a-z]{3}\d{3})-r-br(?<nr>-\d{2})$/)
# open and write to a file with ruby
open('strippedfile.txt', 'w') { |f|
f.print new_contents
}
end
Now what i cant seem to fix, is in the new file "strippedfile" the results are always ["bei640", "-01"] ["bei640", "-02"] ["bei640", "-03"]
And i am trying to get all results in this format:
bei640-01
bei640-02
bei640-03
bei640-04
scan returns an array of matches, you probably want to join them:
- new_contents = str.scan(/^ipc-(?<bng>[a-z]{3}\d{3})-r-br(?<nr>-\d{2})$/)
+ new_contents = str.scan(/^ipc-(?<bng>[a-z]{3}\d{3})-r-br(?<nr>-\d{2})$/).map(&:join)
To print everything without quotes and brackets line by line:
- f.print new_contents
+ f.puts new_contents
Assuming your resultant array is
a = [["bei640", "-02"], ["bei640", "-03"]]
You can use join to get your desired result
a.map{|i| i.join } #=> ["bei640-02", "bei640-03"]
or use shortcut as mudasobwa answered
a.map(&:join) #=> ["bei640-02", "bei640-03"]

'Failed to allocate memory' error with large array

I am trying to import a large text file (approximately 2 million rows of numbers at 260MB) into an array, make edits to the array, and then write the results to a new text file, by writing:
file_data = File.readlines("massive_file.txt")
file_data = file_data.map!(&:strip)
file_data.each do |s|
s.gsub!(/,.*\z/, "")
end
File.open("smaller_file.txt", 'w') do |f|
f.write(file_data.map(&:strip).uniq.join("\n"))
end
However, I have received the error failed to allocate memory (NoMemoryError). How can I allocate more memory to complete the task? Or, ideally, is there another method I can use where I can avoid having to re-allocate memory?
You can read the file line by line:
require 'set'
require 'digest/md5'
file_data = File.new('massive_file.txt', 'r')
file_output = File.new('smaller_file.txt', 'w')
unique_lines_set = Set.new
while (line = file_data.gets)
line.strip!
line.gsub!(/,.*\z/, "")
# Check if the line is unique
line_hash = Digest::MD5.hexdigest(line)
if not unique_lines_set.include? line_hash
# It is unique so add its hash to the set
unique_lines_set.add(line_hash)
# Write the line in the output file
file_output.puts(line)
end
end
file_data.close
file_output.close
You can try reading and writing one line at once:
new_file = File.open('smaller_file.txt', 'w')
File.open('massive_file.txt', 'r') do |file|
file.each_line do |line|
new_file.puts line.strip.gsub(/,.*\z/, "")
end
end
new_file.close
The only thing pending is find duplicated lines
Alternatively you can read file in chunks which should be faster compared to reading it line by line:
FILENAME="massive_file.txt"
MEGABYTE = 1024*1024
class File
def each_chunk(chunk_size=MEGABYTE) # or n*MEGABYTE
yield read(chunk_size) until eof?
end
end
filedata = ""
open(FILENAME, "rb") do |f|
f.each_chunk() {|chunk|
chunk.gsub!(/,.*\z/, "")
filedata += chunk
}
end
ref: https://stackoverflow.com/a/1682400/3035830

How to split the strings to line by line

I have a text file which contains
1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/bin/java
1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/jre/bin/java
1.5.0/opt/itm/v6.2.2/JRE/lx8266/bin/java
1.7.0_72/u01/java/jdk1.7.0_72/jre/bin/java
1.7.0_72/u01/java/jdk1.7.0_72/bin/java
I am trying to read each line by line and get the result by line by line Here is my ruby code:
logfile = "/home/weblogic/javacheck.txt"
java_count = 0
log = Facter::Util::FileRead.read(logfile)
unless log.nil?
log.each_line do |line|
if line.include?('/java')
java_count += 1
val = "#{line}"
But the output is:
"1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/bin/java\n1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/jre/bin/java\n1.5.0/opt/itm/v6.2.2/JRE/lx8266/bin/java\n1.7.0_72/u01/java/jdk1.7.0_72/jre/bin/java\n1.7.0_72/u01/java/jdk1.7.0_72/bin/java\n1.7.0_65/u01/java/jdk1.7.0_65/jre/bin/java\n1.7.0_65/u01/java/jdk1.7.0_65/bin/java\n
How can I convert this string into line by line?
Here is the fix code.
#!/usr/bin/env ruby
logfile = "/home/weblogic/javacheck.txt"
java_count = 0
log = File.open(logfile,"r")
unless log.nil?
log.each_line do |line|
if line.include?('/java')
puts "#{line}"
java_count += 1
end
end
end
puts "#{java_count}"

read file and send data to yml file

i read multipe file and i try to get data in yaml file, but i dont know why i get nothing in my yaml file .
Do you have an idea where i can make a mistake ?
a = array.size
i = 0
array.each do |f|
while i < a
puts array[i]
output = File.new('/home/zyriuse/documents/Ruby-On-Rails/script/Api_BK/licence.yml', 'w')
File.readlines(f).each do |line|
output.puts line
output.puts line.to_yaml
#output.puts YAML::dump(line)
end
i += 1
end
end
There's two problems...
You are initializing i to zero too early... when you process the
first file 'f' you process JUST that first file as many times as you
have files in the array, but for all following files i is now always >= a so you're not doing anything with them.
You are doing File.new in every iteration of 'f' so you are wiping out your last iteration.
This might work better...
output = File.new('licence.yml', 'w')
array.each do |f|
puts f
File.readlines(f).each do |line|
output.puts line
output.puts line.to_yaml
end
end

How to read text file and save last x lines - one line in ruby?

I made it work on two lines.
How would the code look like on one line only? In ruby.
Is the code for last x lines (55 in this case) the best?
code sample
$max_lines_in_log=55
$cron_log = "C:/EduTester/cron/rufus.log"
array = File.read($cron_log).split("\n")[-$max_lines_in_log,$max_lines_in_log]
open($cron_log, 'w') { |f| f.puts array.join("\n") }
`tail -n #{$max_lines_in_log} #{$cron_log} > #{$cron_log}`
I hate writing it in one line but it's what you asked:
File.open("o_f.log", "w") { |o_f| o_f.write File.open("i_f.log") { |i_f| i_f.each_line.each_cons(55).inject{ |a, e| e } } }
Doesn't work if nlines < 55 though, so slightly better version would be:
File.open("o_f.log", "w") { |o_f| o_f.write File.open("i_f.log") { |i_f| i_f.each_line.inject([]){ |ls, l| ls.shift(54).unshift(l) }.reverse } }
File.open(output, 'w'){|out| out.puts File.open(input).readlines[-55,55]}
buff=[]
IO.foreach('c:/test.txt') { |line|
if buff.length < n
buff << line
else
buff.shift
buff << line
end
}
result = buff.join

Resources