Forum: Ruby problem with gsub! in file

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
062bca1c7fca0c9908b56731ace23761?d=identicon&s=25 JenC (Guest)
on 2009-03-24 14:35
(Received via mailing list)
I am new to Ruby and trying to do a find and replace on a text file
based on a regular expression.  When I step through the code line by
line, it appears that the appropriate line in the file is changed, but
when I exit the function, the file hasn't been modified.  Are in-place
edits of files allowed? can you see what it wrong here?

Here is the body of the function:

def ReplaceGuid(guid)
  r = nil
  sconfProj = File.open("myfile.vcproj", "r+").each do |line|
    m = @guidExp.match(line)
    if !m.nil?
      str = m[1]
      r = %r{#{str}}
      line.gsub!(r, guid)
      break
    end
  end
end


Many thanks,
Jen
062bca1c7fca0c9908b56731ace23761?d=identicon&s=25 JenC (Guest)
on 2009-03-24 16:00
(Received via mailing list)
OK, I see now it's not trivial to read and write from a file at the
same time, and instead I should probably just drop to the command line
and call
`ruby -pe 'gsub(/foo/, "bar")' < myfile.vcproj`

When i do this, the text of the file spits out to stdio, and it
appears the substitution has been made, but when I open the file in a
text editor, it hasn't been changed.
Am I missing something?
I already checked file permissions and everything looks fine

Thanks,
Jen

`
Eacf5ed623e72db0b87707baabd6f21a?d=identicon&s=25 Adam Gardner (adamgardner)
on 2009-03-24 16:17
JenC wrote:
> OK, I see now it's not trivial to read and write from a file at the
> same time, and instead I should probably just drop to the command line
> and call
> `ruby -pe 'gsub(/foo/, "bar")' < myfile.vcproj`
>
> When i do this, the text of the file spits out to stdio, and it
> appears the substitution has been made, but when I open the file in a
> text editor, it hasn't been changed.
> Am I missing something?
> I already checked file permissions and everything looks fine
>
> Thanks,
> Jen
>
> `

You'll want ruby -pie 'gsub(/foo/,"bar")'  myfile.vcproj

Or, if you want to keep a backup of the original (and you probably do,
until you know this works the way you expect), you can add an extension
of your choice to the -i flag:

ruby -p -i.bak e 'gsub(/foo/,"bar")'  myfile.vcproj

I've actually never used this on Windows, you'll have to try it and see.
Eacf5ed623e72db0b87707baabd6f21a?d=identicon&s=25 Adam Gardner (adamgardner)
on 2009-03-24 16:19
Adam Gardner wrote:

> ruby -p -i.bak e 'gsub(/foo/,"bar")'  myfile.vcproj

Er, sorry, make that ruby -p -i.bak -e 'gsub(/foo/,"bar")'
myfile.vcproj
062bca1c7fca0c9908b56731ace23761?d=identicon&s=25 JenC (Guest)
on 2009-03-24 17:31
(Received via mailing list)
Thanks Adam.  I tried this:
ruby -p -i.bak -e 'gsub(/foo/,"bar")'  myfile.vcproj

but them I get a whole load of warnings:
-e:1: warning: Can't do inplace edit for stdio

and the file still doesn't change... any ideas?

best,
Jen
Eacf5ed623e72db0b87707baabd6f21a?d=identicon&s=25 Adam Gardner (adamgardner)
on 2009-03-24 17:49
JenC wrote:
> Thanks Adam.  I tried this:
> ruby -p -i.bak -e 'gsub(/foo/,"bar")'  myfile.vcproj
>
> but them I get a whole load of warnings:
> -e:1: warning: Can't do inplace edit for stdio
>
> and the file still doesn't change... any ideas?
>
> best,
> Jen

Are you sure you did just 'myfile.vcproj' and not '< myfile.vcproj'?
062bca1c7fca0c9908b56731ace23761?d=identicon&s=25 JenC (Guest)
on 2009-03-25 09:56
(Received via mailing list)
> Are you sure you did just 'myfile.vcproj' and not '< myfile.vcproj'?
aha!  that was it!

Thanks so much!

On Mar 24, 5:46 pm, Adam Gardner <adam.oddfel...@gmail.com> wrote:
> > Jen
>
770048af205ed307b8cf35ae2282ee2f?d=identicon&s=25 Michael Malone (Guest)
on 2009-03-25 14:28
(Received via mailing list)
>>         sconfProj = File.open("myfile.vcproj", "r+").each do |line|
>> Many thanks,
>> Jen
>>
The problem is this: you're reading the contents of your file into
memory, changing the copy in memory and expecting it to propagate to the
physical file.  Try this: (though I haven't tested or run it, so there
might be some errors)

def ReplaceGuid(guid)
   outfile = File.new("Some_filename", 'w')
   found_match = false
   IO.read("myfile.vcproj").each_line do |line|
      if (@guidExp =~ (line)) && !found_match
         line.gsub!($1, guid)
         found_match = true
      end
      outfile.puts line
   end
   outfile.close
end

That reads in the original and writes the output to a new file.  I'm
assuming you wanted to stop at the first match, which is what would
happen in your original code.

HTH,
Michael


=======================================================================
This email, including any attachments, is only for the intended
addressee.  It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
 altered or corrupted during transmission.
=======================================================================
This topic is locked and can not be replied to.