For example I have file file_name with such content:
Just some text,
nothing more
Then I run kind of this code:
lines = File.open(file_name, "r").readlines
# do something do with lines
File.open(file_name, "w").write(lines)
I'll get this text
"Just some text,"
"nothing more"
How to prevent " sign here? I want text without quotes. Thanks
If you are using ruby 1.9.2, Array#to_s works like Array#inspect. Try this instead (some style tweaks thrown in):
lines = File.readlines(file_name)
File.open(file_name, 'w') { |f| f.write(lines.join) }
If you are only concerned with the quotes enclosing each line
okay, let's try that again
lines.gsub(/^"|"$/, '')
should work
Related
So I have a Ruby script which parses a CSV file as a list of rules and does some processing and returns an array of hashes as processed data.
CSV looks like this:
id_number,rule,notes
1,"dummy_rule","necessary"
2,"sample_rule","optional"
The parsing of CSV looks like this:
def parse_csv(file_name)
filtered_data = []
CSV.foreach(file_name, headers: true) do |row|
filtered_data << row # some processing
end
filtered_data
end
Now I am wondering if it is possible to stub/mock an actual CSV file for unit testing in such a way that I could pass a "filename" into this function. I could make a CSV object and use the generate function but then the actual filename would not be possible.
def test_parse_csv
expected_result = ["id_number"=>1, "rule"=>"dummy_rule", "notes"=>"optional"}]
# stub/mock csv with filename: say "rules.csv"
assert.equal(expected_result, parse_csv(file_name))
end
I use Test::Ruby
I also found a ruby gem library called mocha but I don't know how this works for CSVs
https://github.com/freerange/mocha
Any thoughts are welcome!
I would create a support directory inside your test directory then create a file..
# test/support/rules.csv
id_number,rule,notes
1,"dummy_rule","necessary"
2,"sample_rule","optional"
Your test should look like this, also adding an opening curly bracket which looks like you've missed on line #2.
def test_parse_csv
expected_result = [{"id_number"=>1, "rule"=>"dummy_rule", "notes"=>"optional"}]
assert.equal(expected_result, parse_csv(File.read(csv_file)).first)
end
def csv_file
Rails.root.join('test', 'support', 'rules.csv')
end
EDIT: Sorry, I should have noticed this wasn't Ruby on Rails... heres a ruby solution:
def test_parse_csv
expected_result = [{"id_number"=>1, "rule"=>"dummy_rule", "notes"=>"optional"}]
assert.equal(expected_result, parse_csv(csv_file).first)
end
def csv_file
File.read('test/support/rules.csv')
end
I did this in my test let(:raw_csv) { "row_number \n 1 \n 2" }, telling myself that a CSV file was surely read as a simple string with linebreaks and commas... and it works fine. Be careful with additional whitespaces and commas, it is easy to make a mistake.
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")}}
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
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
The following code is a line in an xml file:
<appId>455360226</appId>
How can I replace the number between the 2 tags with another number using ruby?
There is no possibility to modify a file content in one step (at least none I know, when the file size would change).
You have to read the file and store the modified text in another file.
replace="100"
infile = "xmlfile_in"
outfile = "xmlfile_out"
File.open(outfile, 'w') do |out|
out << File.open(infile).read.gsub(/<appId>\d+<\/appId>/, "<appId>#{replace}</appId>")
end
Or you read the file content to memory and afterwords you overwrite the file with the modified content:
replace="100"
filename = "xmlfile_in"
outdata = File.read(filename).gsub(/<appId>\d+<\/appId>/, "<appId>#{replace}</appId>")
File.open(filename, 'w') do |out|
out << outdata
end
(Hope it works, the code is not tested)
You can do it in one line like this:
IO.write(filepath, File.open(filepath) {|f| f.read.gsub(//<appId>\d+<\/appId>/, "<appId>42</appId>"/)})
IO.write truncates the given file by default, so if you read the text first, perform the regex String.gsub and return the resulting string using File.open in block mode, it will replace the file's content in one fell swoop.
I like the way this reads, but it can be written in multiple lines too of course:
IO.write(filepath, File.open(filepath) do |f|
f.read.gsub(//<appId>\d+<\/appId>/, "<appId>42</appId>"/)
end
)
replace="100"
File.open("xmlfile").each do |line|
if line[/<appId>/ ]
line.sub!(/<appId>\d+<\/appId>/, "<appId>#{replace}</appId>")
end
puts line
end
The right way is to use an XML parsing tool, and example of which is XmlSimple.
You did tag your question with regex. If you really must do it with a regex then
s = "Blah blah <appId>455360226</appId> blah"
s.sub(/<appId>\d+<\/appId>/, "<appId>42</appId>")
is an illustration of the kind of thing you can do but shouldn't.