Reputation: 2241
Got a quick question: I have a file like this:
ip-10-0-12-84.eu-west-1.compute.internal, master, instnum=1, Running
.....
.....
ip-10-0-26-118.eu-west-1.compute.internal, master_rabbit, instnum=4, Running
ip-10-0-26-116.eu-west-1.compute.internal, master_rabbit, instnum=5, Running
.....
ip-10-0-26-68.eu-west-1.compute.internal, sql_master, instnum=9, Running
ip-10-0-13-244.eu-west-1.compute.internal, nat, instnum=2, Running
My goal is to read the file, skipping comments (starts with #
), empty/blank lines and the lines with nat
or master
in it. I tried this:
open('/tmp/runnings.txt').each do |line|
next if line =~ /(^\s*(#|$)|nat|master)/
which is almost working but it also eliminates the lines with master_rabbit
and sql_master
in it. How can I pick only master
and not the any other combination of that? Can it done in the same line? Cheers!!
Upvotes: 4
Views: 2432
Reputation: 13921
I feel this is not a place where the problem should be solved with a regexp. Sure you can get one to work for now, but it will be hard to understand later and harder to edit if you get new keywords to exclude.
I like this way of solving the problem:
FILE_PATH = '/tmp/runnings.txt'
keywords = ['nat', 'master']
empty_lines_and_comments = ->x{ x.chomp.empty? or x.start_with?('#') }
lines_containing_bad_keyword = ->x{ keywords.include? x[1] } # Keywords at index 1
data = File.readlines(FILE_PATH)
.reject(&empty_lines_and_comments)
.map{|line| line.chomp.split(', ')}
.reject(&lines_containing_bad_keyword)
Upvotes: 1
Reputation: 168269
open("/tmp/runnings.txt").each_line
.grep(/\A(?!\s*#)(?!.*\bnat\b)(?!.*\bmaster\b).*\S/) do |line|
...
end
Upvotes: 1
Reputation: 336478
Word boundary anchors can help here:
/^\s*(#|$)|\b(nat|master)\b/
Upvotes: 6