How to overwrite a printed line in the shell with Ruby?
Solution 1
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
Solution 2
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!
Solution 3
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)}
Related videos on Youtube
Steph Thirion
Updated on December 23, 2021Comments
-
Steph Thirion over 2 years
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.
-
Ulysse BN over 5 yearsCame here looking for a solution for multiple lines, someone has an idea?
-
-
cam about 13 yearsHmm, i like @jsegal's solution better, so choose his answer. Remember to
flush
your output still. -
Steph Thirion about 13 yearsI'm divided here, because your answer is a perfectly working snippet of code of what I asked exactly: a solution in Ruby. Yes, it could be more elegant if it used jsegal's suggestion. But a) jsegal's answer is not ruby specific and b) I'd much rather accept an answer with a working snippet. So I'm going to go ahead and edit your answer to reflect jsegal's suggestion, and when/if that edit is accepted, I'll accept your answer and reward jsegal by voting him up. It's the best I can do under this system.
-
Cody Gray about 13 years@Steph: Your dilemma on which answer to accept seems primarily based on the fact that jsegal's answer didn't include a code snippet. Considering Stack Overflow is not a code sharing site, that seems like a fairly arbitrary requirement. You should upvote both answers if you found them useful, and accept the one that helped you the most in finding the solution that worked for you.
-
Steph Thirion about 13 yearsThanks for looking into this @Cody. My dilemma is a little more than that, I think I made it pretty clear that this answer is what I asked for (a solution in Ruby). It also meets the S.O. official guidelines: it is the answer that helped me the most. I was stuck until I tried this snippet (turns out I was not flushing). But I believe Stack Overflow is not just about helping one person on a specific moment, it's about building together a reference for the future. Hence my edit. With this in perspective I'll try to submit the edit again.
-
Nathan Long about 13 yearsNote that if the text output is wider than the current terminal window, you will start seeing line after line of output again.
-
sunsations about 10 yearsTo avoid problems with the current line being short than the previous one. Pad it with the method rjust/ljust e.g. "my output".ljust(80).
-
valk over 6 yearsI have to emphasize the importance of
\r
at the end ofprint
(as @jsegal mentioned) otherwise it won't work. -
Pezholio over 5 yearsThis solution works, but I find putting
\r
at the beginning of each line works better, otherwise the cursor covers the first character of the output (at least on my terminal). Also, make sure you're usingprint
rather thanputs
, asputs
automatically ends each line with a hard (\r\n
) carriage return