search a file and replace text

Discussion in 'Ruby' started by phil.swenson@gmail.com, Apr 3, 2007.

  1. Guest

    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?
     
    , Apr 3, 2007
    #1
    1. Advertising

  2. On 03.04.2007 17:47, wrote:
    > 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
     
    Robert Klemme, Apr 3, 2007
    #2
    1. Advertising

  3. Guest

    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.
     
    , Apr 3, 2007
    #3
  4. On 03.04.2007 18:56, wrote:
    > 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
     
    Robert Klemme, Apr 3, 2007
    #4
  5. Robert Evans Guest

    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/



    On Apr 3, 2007, at 10:00 AM, wrote:

    > 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.
    >
    >
     
    Robert Evans, Apr 4, 2007
    #5
  6. Robert Evans Guest

    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


    On Apr 4, 2007, at 12:39 PM, Robert Evans wrote:

    > 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/
    >
    >
    >
    > On Apr 3, 2007, at 10:00 AM, wrote:
    >
    >> 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.
    >>
    >>

    >
    >
     
    Robert Evans, Apr 4, 2007
    #6
  7. Robert Evans Guest

    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


    On Apr 4, 2007, at 12:44 PM, Robert Evans wrote:

    > 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
    >
    >
    > On Apr 4, 2007, at 12:39 PM, Robert Evans wrote:
    >
    >> 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/
    >>
    >>
    >>
    >> On Apr 3, 2007, at 10:00 AM, wrote:
    >>
    >>> 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.
    >>>
    >>>

    >>
    >>

    >
    >
     
    Robert Evans, Apr 4, 2007
    #7
  8. Emmanuel Oga Guest

    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")

    Phil Swenson wrote:
    > 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?



    --
    Posted via http://www.ruby-forum.com/.
     
    Emmanuel Oga, Apr 4, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dorsa
    Replies:
    0
    Views:
    463
    Dorsa
    Dec 23, 2003
  2. Dan George
    Replies:
    6
    Views:
    191
    Dan George
    Sep 6, 2007
  3. Replies:
    5
    Views:
    517
    Paul Rudin
    Jul 31, 2012
  4. Chris Angelico
    Replies:
    9
    Views:
    234
    Andrew Cooper
    Jul 29, 2012
  5. Tim Chase
    Replies:
    10
    Views:
    385
    Robert Miles
    Aug 31, 2012
Loading...

Share This Page