How to replace multiple newlines in a row with one newline using Ruby - ruby

I have a script written in ruby. I need to remove any duplicate newlines (e.g.)
\n
\n
\n
to
\n
My current attempt worked (or rather not) using
str.gsub!(/\n\n/, "\n")
Which gave me no change to the output. What am I doing wrong?

This works for me:
#!/usr/bin/ruby
$s = "foo\n\n\nbar\nbaz\n\n\nquux";
puts $s
$s.gsub!(/[\n]+/, "\n");
puts $s

Use the more idiomatic String#squeeze instead of gsub.
str = "a\n\n\nb\n\n\n\n\n\nc"
str.squeeze("\n") # => "a\nb\nc"

You need to match more than one newline up to an infinite amount. Your code example will work with just a minor tweak:
str.gsub!(/\n+/, "\n")
For example:
str = "this\n\n\nis\n\n\n\n\na\ntest"
str.gsub!(/\n+/, "\n") # => "this\nis\na\ntest"

are you sure it shouldn't be /\n\n\n/, "\n" that what you seem to be wanting in your question above.
also, are you sure it's not doing a windows new-line "\r\n"?
EDIT: Additional info
Per Comment
"The amount of newlines can change. Different lines have between 2 and 5 newlines."
if you only want to hit the 2-5 lines try this
/\n{2,5}/, "\n"

Simply splitting and recombining the lines will give the desired result
>> "one\ntwo\n\nthree\n".split.join("\n")
=> "one\ntwo\nthree"
Edit: I just noticed this will replace ALL whitespace substrings with newlines, e.g.
>> "one two three\n".split.join("\n")
=> "one\ntwo\nthree"
First check that this is what you want!

Simply calling split will also trim out all of your whitespace.
You need to pass \n to split
>> "one ok \ntwo\n\nthree\n".split(/\n+/).join("\n")
=> "one ok \ntwo\nthree"

Additionally, also works with
spaces on blank lines
n number of back to back blank lines
str.gsub! /\n^\s*\n/, "\n\n"
where,
\n is of course newline
\s is space
denotes 1 or more spaces along when used after \s

Try This It Worked for me:
s = test\n\n\nbar\n\n\nfooo
s.gsub("\n\n", '')

Ruby needs the backslashes escaped differently than you have provided.
str.sub!("\\\\n+\\\\n","\\\\n")
http://www.ruby-forum.com/topic/176239

Related

Wants to echo new line character

I wants to echo \n like in this way using ruby language:
`echo "array = text.split(/\n/)" > demo`
and demo file should contain output in this way:
array = text.split(/\n/)
But instead to above i am getting in this way, \n produce new line in real which i dont want:
array = text.split(/
/)
Please let me know any options, I already tried backslash and ^ but none of this useful.
If you want to stick with regexps, double-backslash your \n
`echo "array = text.split(/\\n/)" > demo`
You could use split("\n") instead of a regexp.
There are 6 backslash needed here, Like this:
`echo "array = text.split(/\\\\\\n/)" > demo`
This produce excellent results.

Regexp for certain character to end of line

I have a string
"So on and so forth $5.99"
I would like to extract everything after the $ until the end of the line.
/$ finds the character $. How do I select the rest of the string? I know it's something \z but I can't get the syntax right.
In regexp $ represents the end of the line.
So in your case you need \$.*$ To include your escaped $ and everything (.*) up until the end of the line $.
No, /$ does not match that character. You need to escape it \ to match a literal.
string = "So on and so forth $5.99"
result = string.match(/\$(.*)$/)
puts result[1] #=> "5.99"
If you want to capture everything after the $, you'll want:
/\$(.*)\z/
See http://rubular.com/r/T4fR1SEl3j

How to escape newline in regex scan

str = "This\n is a sample text for test"
str.scan(/\S.{0,15}\S(?=\s|$)|\S+/)
# => ["This", "is a sample text", "for test"]
Here, it splits when the newline (\n) is present. I actually want the output as,
["This\n is a", "sample text for", "test"]
How can I achieve that?
Use the /m modifier which allows the dot to match newlines:
str.scan(/\S.{0,15}\S(?=\s|\z)|\S+/m)
Also, I suggest you use \z instead of $ because $ matches the end of a line; \z is the only way to force Ruby to match the end of the string. It doesn't matter in this example, but it's a good habit to get into. Ruby differs from all other regex flavors in these two points.

Reading from stdin and printing to stdout in Ruby

This question is kinda simple (don't be so harsh with me), but I can't get a code-beautiful solution. I have the following code:
ARGF.each_line do |line|
arguments = line.split(',')
arguments.each do |task|
puts "#{task} result"
end
end
It simply read from the standard input numbers. I use it this way:
echo "1,2,3" | ruby prog.rb
The output desired is
1 result
2 result
3 result
But the actual output is
1 result
2 result
3
result
It seems like there's a newline character introduced. I'm skipping something?
Each line ends in a newline character, so splitting on commas in your example means that the last token is 3\n. Printing this prints 3 and then a newline.
Try using
arguments = line.chomp.split(',')
To remove the trailing newlines before splitting.
Your stdin input includes a trailing newline character. Try calling line.chomp! as the first instruction in your each_line block.

pattern matching in ruby

cud any body tell me how this expression works
output = "#{output.gsub(/grep .*$/,'')}"
before that opearation value of ouptput is
"df -h | grep /mnt/nand\r\n/dev/mtdblock4 248.5M 130.7M 117.8M 53% /mnt/nand\r\n"
but after opeartion it comes
"df -h | \n/dev/mtdblock4 248.5M 248.5M 130.7M 117.8M 53% /mnt/nand\r\n "
plzz help me
Your expression is equivalent to:
output.gsub!(/grep .*$/,'')
which is much easier to read.
The . in the regular expression matches all characters except newline by default. So, in the string provided, it matches "grep /mnt/nand", and will substitute a blank string for that. The result is the provided string, without the matched substring.
Here is a simpler example:
"hello\n\n\nworld".gsub(/hello.*$/,'') => "\n\n\nworld"
In both your provided regex, and the example above, the $ is not necessary. It is used as an anchor to match the end of a line, but since the pattern immediately before it (.*) matches everything up to a newline, it is redundant (but does not cause harm).
Since gsub returns a string, your first line is exactly the same as
output = output.gsub(/grep .*$/, '')
which takes the string and removes any occurance of the regexp pattern
/grep .*$/
i.e. all parts of the string that start with 'grep ' until the end of the string or a line break.
There's a good regexp tester/reference here. This one matches the word "grep", then a space, then any number of characters until the next line-break (\r or \n). "." by itself means any character, and ".*" together means any number of them, as many as possible. "$" means the end of a line.
For the '$', see here http://www.regular-expressions.info/reference.html
".*$" means "take every character from the end of the string" ; but the parser will interpret the "\n" as the end of a line, so it stops here.

Resources