search a file and replace text

P

phil.swenson

I need to search a specific xml file in a directory, look for:

<port system-property="tangosol.coherence.clusterport">30890</port>

and if the port 30890 is still there replace it with a different
integer.

I know of several ways to do this (like open the file, iterate the
lines until I find the integer, do a gsub! on on the integer). But it
seems like there might be a better way to do it. Is there a search
and replace API I don't know about?

Any thoughts?
 
R

Robert Klemme

I need to search a specific xml file in a directory, look for:

<port system-property="tangosol.coherence.clusterport">30890</port>

and if the port 30890 is still there replace it with a different
integer.

I know of several ways to do this (like open the file, iterate the
lines until I find the integer, do a gsub! on on the integer). But it
seems like there might be a better way to do it. Is there a search
and replace API I don't know about?

Look for ruby -pi.bak -e 'gsub ...'

robert
 
P

phil.swenson

well I *THOUGHT* I knew how to do it, here's my first crack at it:

file_name = base_config_path + '/Caching/tangosol-
coherence.xml'
File.open(file_name, File::RDWR).each{ |line|
if line.gsub!(/30890/, port.to_s)
puts "tangosol port overridden with %d" % port
break
end
}


The gsub doesn't modify the line, guess it just modifies the string.
How do I actually modify the file itself?

btw, I did look at rexml but it looked like overkill for this. I'll
take another look though.
 
R

Robert Klemme

well I *THOUGHT* I knew how to do it, here's my first crack at it:

file_name = base_config_path + '/Caching/tangosol-
coherence.xml'
File.open(file_name, File::RDWR).each{ |line|
if line.gsub!(/30890/, port.to_s)
puts "tangosol port overridden with %d" % port
break
end
}


The gsub doesn't modify the line, guess it just modifies the string.
Exactly.

How do I actually modify the file itself?

Read it, modify it, write it. Or use ruby -pi.bak ...

robert
 
R

Robert Evans

gsub! is destructive - it edits in-place and does not return a value.
You could get a value back from gsub, but then you'd need to do
something with that value.

The following worked, though I don't consider it elegant:

require 'fileutils'

File.open("/tmp/replaceable2.txt", 'w+') do | new_file |
new_file.puts(File.open('/tmp/replaceable.txt', 'r') do |
original_file |
original_file.read.gsub('30890', '44444')
end)
end
FileUtils.mv("/tmp/replaceable2.txt", "/tmp/replaceable.txt")

If you don't want the intermediate file, you could do something like
this:

new_str = File.open('/tmp/replaceable.txt', 'r') { | f | f.read.gsub
('30890', '44444') }
File.open('/tmp/replaceable.txt', w+) { |f| f.puts new_str }

Bob
http://www.junitfactory.com/
 
R

Robert Evans

Actually, that was pretty sloppy, by opening the file in read-write
mode, and then rewinding after the read, we can overwrite it with the
changes in a one-liner:

File.open("/tmp/replaceable.txt", 'r+') { |f| newstr = f.read.gsub
('33333', '00000'); f.rewind; f.puts(newstr) }

Bob
 
R

Robert Evans

And note, this won't erase any left over old file contents that
extend beyond the length of the current file, e.g., if the port
number is a shorter number of characters than the old port number.

Bob
 
E

Emmanuel Oga

def ChangeOnFile(file, regex_to_find, text_to_put_in_place)
text= File.read file
File.open(file, 'w+'){|f| f << text.gsub(regex_to_find,
text_to_put_in_place)}
end

Then:

ChangeOnFile('/etc/myfile.conf', /30890/, "32737")
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top