I have a loop which read lines from text file :
text = File.open("file.txt").read
text.gsub!(/\n\r?/, "\n", )
text.each_line do |line|
# do something with line
end
And in each iteration I get line with " " in the end of line : "word ", and I need get just "word"
How fix my problem?
ll = line.clone.sub!(" ", "") - returns nil
You might want to use String#strip or one of the similar methods to remove whitespace. In this example String#rstrip seems to be an option:
text.each_line do |line|
sanitized_line = line.rstrip
# ...
end
line.gsub!(/\s+/, "") - fixed my problem.
Related
New to ruby here!
How to replace the whole line in a text file which contains a specific string using ruby?
Example: I want to remove and add the whole line contains "DB_URL" and add something like "DB_CON=jdbc:mysql:replication://master,slave1,slave2,slave3/test"
DB_URL=jdbc:oracle:thin:#localhost:TEST
DB_USERNAME=USER
DB_PASSWORD=PASSWORD
Here is your solution.
file_data = ""
word = 'Word you want to match in line'
replacement = 'line you want to set in replacement'
IO.foreach('pat/to/file.txt') do |line|
file_data += line.gsub(/^.*#{Regexp.quote(word)}.*$/, replacement)
end
puts file_data
File.open('pat/to/samefile.txt', 'w') do |line|
line.write file_data
end
Here is my attempt :
file.txt
First line
Second line
foo
bar
baz foo
Last line
test.rb
f = File.open("file.txt", "r")
a = f.map do |l|
(l.include? 'foo') ? "replacing string\n" : l # Please note the double quotes
end
p a.join('')
Output
$ ruby test.rb
"First line\nSecond line\nreplacing string\nbar\nreplacing string\nLast line"
I commented # Please note the double quotes because single quotes will escape the \n (that will become \\n). Also, you might want to think about the last line of your file since it will add \n at the end of the last line when there will not have one at the end of your original file. If you don't want that you could make something like :
f = File.open("file.txt", "r")
a = f.map do |l|
(l.include? 'foo') ? "replacing string\n" : l
end
a[-1] = a[-1][0..-2] if a[-1] == "replacing string\n"
p a.join('')
Output.txt = report_fail_20150818_13_23.txt
I want to read output.txt from 8th character to 11th so that it can print fail.
fo = open("output.txt", "r+")
str = fo.read(8,11);
print "Read String is : ", str
fo.close()
You need to read the line first, then get the word from that line. Use the .readline() method (Docs).
Here is the correct way according to the example in the question:
fo = open("output.txt", "r+")
str = fo.readline()
str = str[7:11]
print "Read String is : ", str
fo.close()
However, for the best practise use a with statement:
with open('myfile.txt', 'r') as fo:
str = fo.readline()
str = str[7:11]
print "Read String is : ", str
with automatically closes the file when the block ends. If you are using Python 2.5 or lower, you have to include from __future__ import with_statement.
Code:
class Comparer
words = "asdf-asdf-e-e-a-dsf-bvc-onetwothreefourfive-bob-john"
foundWords = []
File.foreach('words.txt') do |line|
substr = "#{line}"
if words.include? substr
puts "Found " + substr
foundWords << substr
end
end
wordList = foundWords.join("\n").to_s
puts "Words found: " + wordList
end
words.txt:
one
blah-blah-blah
123-5342-123123
onetwo
onetwothree
onetwothreefour
I'd like the code to return all instances of include?, however when the code is run, wordList only contains the last line of words.txt ("onetwothreefour".) Why don't the other lines in words.txt get factored?
Because all other lines you expect to be found, they have "hidden" newline character at the end. You can see for yourself.
File.foreach('words.txt') do |line|
puts line.inspect
# or
p line
end
You can get rid of newlines by using chomp! method on line.
File.foreach('words.txt') do |line|
line.chomp!
# proceed with your logic
end
I am writing a test script that opens a file with a list of URLs without the "www" and "com".
I am trying to read each line and put the line into the URL. I then check to see if it redirects or even exists.
My problem is when I read the line from the file and assign it to a variable. I then do a compare with what's in the URL after loading and what I initially put in there, but it seems to be adding a return after my variable.
Basically it is always saying redirect because it puts "http://www.line\n.com/".
How can I get rid of the "\n"?
counter = 1
file = File.new("Data/activeSites.txt", "r")
while (line = file.gets)
puts "#{counter}: #{line}"
counter = counter + 1
browser.goto("http://www." + line + ".com/")
if browser.url == "http://www." + line + ".com/"
puts "Did not redirect"
else
puts ("Redirected to " + browser.url)
#puts ("http://www." + line + ".com/")
puts "http://www.#{line}.com/"
end
Basically it is always saying redirect because it puts http://www.line and then return .com/
How can I get rid of the return?
Short answer: strip
"text\n ".strip # => "text"
Long answer:
Your code isn't very ruby-like and could be refactored.
# Using File#each_line, the line will not include the newline character
# Adding with_index will add the current line index as a parameter to the block
File.open("Data/activeSites.txt").each_line.with_index do |line, counter|
puts "#{counter + 1}: #{line}"
# You're using this 3 times already, let's make it a variable
url = "http://#{line}.com"
browser.goto(url)
if browser.url == url
puts "Did not redirect"
else
puts ("Redirected to " + browser.url)
puts url
end
end
That's because your lines are terminated by a newline. You need to strip it off:
while (line = file.gets)
line.strip!
puts "#{counter}: #{line}"
# ...
Note that there are better ways of iterating over the lines in a file:
File.foreach("Data/activeSites.txt") do |line|
# ...
end
This is your code after reindenting it to the "Ruby way":
counter = 1
file = File.new("Data/activeSites.txt", "r")
while (line = file.gets)
puts "#{counter}: #{line}"
counter = counter + 1
browser.goto("http://www." + line + ".com/")
if browser.url == "http://www." + line + ".com/"
puts "Did not redirect"
else
puts ("Redirected to " + browser.url)
#puts ("http://www." + line + ".com/")
puts "http://www.#{line}.com/"
end
It's not correct because it's missing a closing end for the while. But, it's also not dealing with file IO correctly.
This is how I'd write it:
File.foreach("Data/activeSites.txt") do |line|
puts "#{ $. }: #{ line }"
browser.goto("http://www.#{ line }.com/")
if browser.url == "http://www.#{ line }.com/"
puts "Did not redirect"
else
puts "Redirected to #{ browser.url }"
puts "http://www.#{ line }.com/"
end
end
File.foreach is a method inherited from IO. If you read the file correctly you don't need to strip or chomp, because Ruby will handle it correctly when IO.foreach reads the line.
Every time IO reads a line it increments the $. global, which is short-hand for $INPUT_LINE_NUMBER. There's no need to keep a counter. Using:
require 'english'
will enable the verbose names. See the English docs for more information.
How would I overwrite the previously printed line in a Unix shell with Ruby?
Say I'd like to output the current time on a shell every second, but instead of stacking down each time string, I'd like to overwrite the previously displayed time.
You can use the \r escape sequence at the end of the line (the next line will overwrite this line). Following your example:
require 'time'
loop do
time = Time.now.to_s + "\r"
print time
$stdout.flush
sleep 1
end
Use the escape sequence \r at the end of the line - it is a carriage return without a line feed.
On most unix terminals this will do what you want: the next line will overwrite the previous line.
You may want to pad the end of your lines with spaces if they are shorter than the previous lines.
Note that this is not Ruby-specific. This trick works in any language!
Here is an example I just wrote up that takes an Array and outputs whitespace if needed. You can uncomment the speed variable to control the speed at runtime. Also remove the other sleep 0.2 The last part in the array must be blank to output the entire array, still working on fixing it.
##speed = ARGV[0]
strArray = [ "First String there are also things here to backspace", "Second Stringhereare other things too ahdafadsf", "Third String", "Forth String", "Fifth String", "Sixth String", " " ]
#array = [ "/", "-", "|", "|", "-", "\\", " "]
def makeNewLine(array)
diff = nil
print array[0], "\r"
for i in (1..array.count - 1)
#sleep #speed.to_f
sleep 0.2
if array[i].length < array[i - 1].length
diff = array[i - 1].length - array[i].length
end
print array[i]
diff.times { print " " } if !diff.nil?
print "\r"
$stdout.flush
end
end
20.times { makeNewLine(strArray) }
#20.times { makeNewLine(array)}
Following this answer for bash, I've made this method:
def overwrite(text, lines_back = 1)
erase_lines = "\033[1A\033[0K" * lines_back
system("echo \"\r#{erase_lines}#{text}\"")
end
which can be used like this:
def print_some_stuff
print("Only\n")
sleep(1)
overwrite("one")
sleep(1)
overwrite("line")
sleep(1)
overwrite("multiple\nlines")
sleep(1)
overwrite("this\ntime", 2)
end
You can use
Ruby module curses, which was part of the Ruby standard library
Cursor Movement
puts "Old line"
puts "\e[1A\e[Knew line"
See also Overwrite last line on terminal: