Delete a line of information from a text file - ruby

I have a text file called text.txt, and it has the following text:
123,shirt,9.99
234,pants,19.50
456,socks,3.99
How do I delete one row (e.g 123,shirt,9.99). How would I go about deleting this row?
My code so far:
test_file = File.new('text.txt', "a")
while (line = test_file)
puts 'Enter the products item number you wish to delete. '
user_delete = gets.chomp.to_i
line.delete(user_delete)
end

You're making a lot of mistakes here.
First of all opening the file with a (you need to use r+ or w+).
In Ruby we use a more elegant to iterate over files.
Check this answer, it will help you with your problem.
After that a look at IO library to understand how it all works

I imagine there are a bunch of better ways to do this, but here's quick and dirty:
puts "What's the item number?"
item_num = gets.chomp
read_file = File.new('read.txt', "r").read
write_file = File.new('read.txt', "w")
read_file.each_line do |line|
write_file.write(line) unless line.include? item_num
end

Related

How do I search a text file for a string and then print/return/put out what line of the file it was found on as a number in Ruby

So, I want to use the number I get from it in this:
line = answer to question
database.read.lines[line]
Database being the text file I am searching in.
You can also do it this way :
text_to_find = 'some random text' # use gets method to take input from user
text_found_at_index = database.readlines.index{|line| not line[text].nil? }
Hope, this is what you require : )
I would try something like this:
query = gets.chomp
database.each_line.with_index do |line, index|
if line.include?(query)
puts "Line #{index}: #{line}"
end
end

How to name just created .TXT files in such a way that file name differs each time

I have compiled the user's answers into a .TXT file and move it to another location, where I would store all the answers. I would need that .TXT to be named differently each time a user runs the application, so that the file is not replaced. I thought about appending time stamps next to the original name, but not sure how to do that.
My code:
require 'FileUtils'
puts "1) How would you rate the manual? Range: 1-10."
rating_range = gets.to_i
puts "2) How could the manual be improved? Type your answer below:"
improvement = gets.chomp
puts "3) What would you add to the manual. Type your answer below:"
addition = gets.chomp
puts "4) Indicate any general comments you would like to add:"
general_comments = gets.chomp
File.open("Survey.txt", 'w') { |file|
file << "1) #{rating_range}\n"
file << "2) #{improvement}\n"
file << "3) #{addition}\n"
file << "4) #{general_comments}\n"
}
FileUtils.mv('/Documents/Survey.txt', '/Stuff')
The file Survey.txt should be named differently each time.
Any ideas?
Time.now
http://ruby-doc.org/core-2.2.0/Time.html
filename = "Survey-#{Time.now}"
File.open(filename, 'w')
FileUtils.mv(filename, '/Stuff')
Timestamps aren't really guaranteed to be unique. Although it's unlikely you'd get exact duplicates, it's still possible. If you're looking for a file solution, you can use a UUID:
require 'securerandom'
uuid = SecureRandom.uuid
File.open("Survey-#{uuid}.txt", 'w') { |file|
...
}
Of course for a more robust solution, you should be using a database. :)
Try replacing
File.open("Survey.txt", 'w') { |file|
with
File.open("Survey_" + Time.now.to_i.to_s + ".txt", 'w') { |file|
This will append the time in seconds since the unix epoch to the filename. If you just use Time.now you'll end up with characters like colons in the filename, which could be problematic depending on your filesystem.
Do you just want to differentiate files, or does the timestamp need to be readable?

Read from a file and Update

i have a text file called text.txt with stored text like so
713,socks,3.99
888,hat,12.99
634,shirt,7.99
I want to open my file and choose a item number then i want to update the description and price. and save that back to the file.
heres my code so far
puts "Whats's the item number of the product you wish to update?"
item_num = gets.chomp
puts 'Enter new products description. '
new_description = gets.chomp
puts 'Enter new products price. '
new_price = gets.chomp.to_s
open('text.txt', 'r+') { |update|
update.puts "#{item_num},#{new_description},#{new_price}"
}
end
all this is doing is adding a new product with the same item number.
The easiest way to achieve a goal is to use CSV class to operate your file content. After all, the content is csv, right?
So, instead of:
open('text.txt', 'r+') { |update|
update.puts "#{item_num},#{new_description},#{new_price}"
}
you might want to search for an element inside loaded array, update it and then write the content back to file:
require 'csv'
items = CSV.read("text.txt")
items.map! { |i|
next i unless i.first == item_num # skip unless it’s our item
i[1] = new_description
i[2] = new_price
i
}
# here should go the code whether you need to insert line if `num` is not found
CSV.open("text.txt", "wb") do |csv|
items.each { |i| csv << i }
end
This is definitely not a best production-quality code, the intent was to demonstrate how it’s to be done in general. Hope it helps.

Ruby: How to replace text in a file?

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.

trying to get the delta between columns using FasterCSV

A bit of a noob here so apologies in advance.
I am trying to read a CSV file which has a number of columns, I would like see if one string "foo" exists anywhere in the file, and if so, grab the string one cell over (aka same row, one column over) and then write that to a file
my file c.csv:
foo,bar,yip
12,apple,yap
23,orange,yop
foo,tom,yum
so in this case, I would want "bar" and "tom" in a new csv file.
Here's what I have so far:
#!/usr/local/bin/ruby -w
require 'rubygems'
require 'fastercsv'
rows = FasterCSV.read("c.csv")
acolumn = rows.collect{|row| row[0]}
if acolumn.select{|v| v =~ /foo/} == 1
i = 0
for z in i..(acolumn).count
puts rows[1][i]
end
I've looked here https://github.com/circle/fastercsv/blob/master/examples/csv_table.rb but I am obviously not understanding it, my best guess is that I'd have to use Table to do what I want to do but after banging my head up against the wall for a bit, I decided to ask for advice from the experienced folks. help please?
Given your input file c.csv
foo,bar,yip
12,apple,yap
23,orange,yop
foo,tom,yum
then this script:
#!/usr/bin/ruby1.8
require 'fastercsv'
FasterCSV.open('output.csv', 'w') do |output|
FasterCSV.foreach('c.csv') do |row|
foo_index = row.index('foo')
if foo_index
value_to_the_right_of_foo = row[foo_index + 1]
output << value_to_the_right_of_foo
end
end
end
will create the file output.csv
bar
tom

Resources