Ruby read/write to file in 1 line of code - ruby

I am kind of a newbie to Ruby, I am working out some katas and I stuck on this silly problem. I need to copy the content of 1 file to a new file in 1 line of code
First try:
File.open(out, 'w').write(File.open(in).read)
Nice, but it's wrong I need to close the files:
File.open(out, 'w') { |outf| outf.write(File.open(in).read) }
And then of course close the read:
File.open(out, 'w') { |outf| File.open(in) { |inf| outf.write(outf.read)) } }
This is what I come up with, but it does not look like 1 line of code to me :(
Ideas?
Regards,

Ruby 1.9.3 and later has a
File.write(name, string, [offset], open_args)
command that allows you to write a file directly. name is the name of the file, string is what you want to write, and the other arguments are above my head.
Some links for it: https://github.com/ruby/ruby/blob/ruby_1_9_3/NEWS , http://bugs.ruby-lang.org/issues/1081 (scroll to the bottom).

There are many ways. You could simply invoke the command line for example:
`cp path1 path2`
But I guess you're looking for something like:
File.open('foo.txt', 'w') { |f| f.write(File.read('bar.txt')) }

You can do the following:
File.open(out_file, "w") {|f| f.write IO.read(in_file)}

You can try:
IO.binwrite('to-filename', IO.binread('from-filename'))
Check the ruby docs:
IO::binwrite & IO::binread

Related

Ruby blank line in file won't remove

I must've browsed every solution on StackOverflow, nothing seems to be removing the blank line's from text file which looks like this:
google
yahoo
facebook
reddit
Amongst other sources, I've tried:
File.foreach("file.txt") { |line|
line.gsub(/^$\n/, '')
}
and
replace = text.gsub /^$\n/, ''
File.open("file.txt", "w") { |file| file.puts replace }
However, these aren't working. I'm tearing my hair out, it seems that there is no native Nokogiri method, and regular expressions aren't working either.
How about you check if it is empty instead?
out = File.new("out.txt", "w")
File.foreach("file.txt") { |line|
out.puts line unless line.chomp.empty?
}
I use below one liner to delete all blank lines from a file
file = "/tmp/hello.log"
File.write(file, File.read(file).gsub(/\n+/,"\n"))
Change the gsub a little bit and it will work
File.foreach("file.txt"){|line|
line.gsub("\n", '')
}
source_file = '/hello.txt'
new_file = File.new('/hello_new.txt')
File::open(new_file,'w') do |file|
File::open(source_file,'r').each(sep="\n") do |line|
file << line unless line.gsub("\n",'').length == 0
end
end
String#squeeze is nice for this. Here it reduces series of line-ends to a single line-end.
open("out.txt", "w") {|out| open("test.txt") {|in| out << in.read.squeeze("\n")}}

Adding specific lines to a file with Ruby

Im trying to edit a file with a ruby scriopt to add a html tag eg at the beginning of the file and line breaks eg. at the end of each line.
Cannot find a clear example to do this.
Any help will be much appreciated.
Thanks
Here is example code that does what you need(you need to call the modify_file function):
def add_tag(tag, str)
return "<#{tag}>\n#{str}\n</#{tag}>"
end
def modify_file(filename)
content = ""
File.open(filename){|file| content = file.read}
content.gsub(/\n/, "</br>\n")
content = add_tag("html", content)
File.open(filename, "w") {|file| file.write(content)}
end

How can I copy the contents of one file to another using Ruby's file methods?

I want to copy the contents of one file to another using Ruby's file methods.
How can I do it using a simple Ruby program using file methods?
There is a very handy method for this - the IO#copy_stream method - see the output of ri copy_stream
Example usage:
File.open('src.txt') do |f|
f.puts 'Some text'
end
IO.copy_stream('src.txt', 'dest.txt')
For those that are interested, here's a variation of the IO#copy_stream, File#open + block answer(s) (written against ruby 2.2.x, 3 years too late).
copy = Tempfile.new
File.open(file, 'rb') do |input_stream|
File.open(copy, 'wb') do |output_stream|
IO.copy_stream(input_stream, output_stream)
end
end
As a precaution I would recommend using buffer unless you can guarantee whole file always fits into memory:
File.open("source", "rb") do |input|
File.open("target", "wb") do |output|
while buff = input.read(4096)
output.write(buff)
end
end
end
Here my implementation
class File
def self.copy(source, target)
File.open(source, 'rb') do |infile|
File.open(target, 'wb') do |outfile2|
while buffer = infile.read(4096)
outfile2 << buffer
end
end
end
end
end
Usage:
File.copy sourcepath, targetpath
Here is a simple way of doing that using ruby file operation methods :
source_file, destination_file = ARGV
script = $0
input = File.open(source_file)
data_to_copy = input.read() # gather the data using read() method
puts "The source file is #{data_to_copy.length} bytes long"
output = File.open(destination_file, 'w')
output.write(data_to_copy) # write up the data using write() method
puts "File has been copied"
output.close()
input.close()
You can also use File.exists? to check if the file exists or not. This would return a boolean true if it does!!
Here's a fast and concise way to do it.
# Open first file, read it, store it, then close it
input = File.open(ARGV[0]) {|f| f.read() }
# Open second file, write to it, then close it
output = File.open(ARGV[1], 'w') {|f| f.write(input) }
An example for running this would be.
$ ruby this_script.rb from_file.txt to_file.txt
This runs this_script.rb and takes in two arguments through the command-line. The first one in our case is from_file.txt (text being copied from) and the second argument second_file.txt (text being copied to).
You can also use File.binread and File.binwrite if you wish to hold onto the file contents for a bit. (Other answers use an instant copy_stream instead.)
If the contents are other than plain text files, such as images, using basic File.read and File.write won't work.
temp_image = Tempfile.new('image.jpg')
actual_img = IO.binread('image.jpg')
IO.binwrite(temp_image, actual_img)
Source: binread,
binwrite.

Find and replace in a file in Ruby

I have this little program I write in ruby. I found a nice piece of code here, on SO, to find and replace something in a file, but it doesn't seems to work.
Here's the code:
#!/usr/bin/env ruby
DOC = "test.txt"
FIND = /,,^M/
SEP = "\n"
#make substitution
File.read(DOC).gsub(FIND, SEP)
#Check if the line already exist
unique_lines = File.readlines(DOC).uniq
#Save the result in a new file
File.open('test2.txt', 'w') { |f| f.puts(unique_lines) }
Thanks everybody !
I skip the check you make to see if the line already exists and usually go with something like this (here I want to replace 'FOO' with 'BAR'):
full_path_to_read = File.expand_path('~/test1.txt')
full_path_to_write = File.expand_path('~/test2.txt')
File.open(full_path_to_read) do |source_file|
contents = source_file.read
contents.gsub!(/FOO/, 'BAR')
File.open(full_path_to_write, "w+") { |f| f.write(contents) }
end
The use of expand_path is also probably a bit pedantic here, but I like it just so that I don't accidentally clobber some file I didn't mean to.

How to write to file in Ruby?

I need to read the data out of database and then save it in a text file.
How can I do that in Ruby? Is there any file management system in Ruby?
Are you looking for the following?
File.open(yourfile, 'w') { |file| file.write("your text") }
You can use the short version:
File.write('/path/to/file', 'Some glorious content')
It returns the length written; see ::write for more details and options.
To append to the file, if it already exists, use:
File.write('/path/to/file', 'Some glorious content', mode: 'a')
This is preferred approach in most cases:
File.open(yourfile, 'w') { |file| file.write("your text") }
When a block is passed to File.open, the File object will be automatically closed when the block terminates.
If you don't pass a block to File.open, you have to make sure that file is correctly closed and the content was written to file.
begin
file = File.open("/tmp/some_file", "w")
file.write("your text")
rescue IOError => e
#some error occur, dir not writable etc.
ensure
file.close unless file.nil?
end
You can find it in documentation:
static VALUE rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
VALUE io = rb_class_new_instance(argc, argv, klass);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
}
return io;
}
The Ruby File class will give you the ins and outs of ::new and ::open but its parent, the IO class, gets into the depth of #read and #write.
Zambri's answer found here is the best.
File.open("out.txt", '<OPTION>') {|f| f.write("write your stuff here") }
where your options for <OPTION> are:
r - Read only. The file must exist.
w - Create an empty file for writing.
a - Append to a file.The file is created if it does not exist.
r+ - Open a file for update both reading and writing. The file must exist.
w+ - Create an empty file for both reading and writing.
a+ - Open a file for reading and appending. The file is created if it does not exist.
In your case, w is preferable.
For those of us that learn by example...
Write text to a file like this:
IO.write('/tmp/msg.txt', 'hi')
BONUS INFO ...
Read it back like this
IO.read('/tmp/msg.txt')
Frequently, I want to read a file into my clipboard ***
Clipboard.copy IO.read('/tmp/msg.txt')
And other times, I want to write what's in my clipboard to a file ***
IO.write('/tmp/msg.txt', Clipboard.paste)
*** Assumes you have the clipboard gem installed
See: https://rubygems.org/gems/clipboard
To destroy the previous contents of the file, then write a new string to the file:
open('myfile.txt', 'w') { |f| f << "some text or data structures..." }
To append to a file without overwriting its old contents:
open('myfile.txt', "a") { |f| f << 'I am appended string' }

Resources