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. Advertisements

  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. Advertisements

  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

    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

    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

    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

    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. Advertisements

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:
    539
    Dorsa
    Dec 23, 2003
  2. Dan George
    Replies:
    6
    Views:
    268
    Dan George
    Sep 6, 2007
  3. Replies:
    5
    Views:
    672
    Paul Rudin
    Jul 31, 2012
  4. Chris Angelico
    Replies:
    9
    Views:
    341
    Andrew Cooper
    Jul 29, 2012
  5. Tim Chase
    Replies:
    10
    Views:
    586
    Robert Miles
    Aug 31, 2012
Loading...

Share This Page