modify the file (a little triky one)

shireeshn

Member
hi every body,

i have a small requirement, this is achivable i dont know, if possible please give me suggestions.

I have to a file (c:\abc.txt), let us think there is a large amount of data.
now i want to find a word in the file and replace with diffrent wrod in the same file.

Note:- New file creation is not allowed, boz create date of file will change, this should not happen. only modify date should change.


Can any one help me in this.

Thanks in advance.
 

TomBascom

Curmudgeon
You could, in theory, cobble something together with READKEY and SEEK.

Just don't expect it to be fast ;)

(This is really a job for a specialized tool like "sed" on UNIX.)
 

TomBascom

Curmudgeon
This will do the trick so long as the old and new strings are the same length.

Handling strings of differing length is an exercise left to the student ;)

Code:
/* sed.p
 */

define variable inLine    as character no-undo.
define variable outLine   as character no-undo.
define variable txtLength as integer   no-undo.
define variable offsetIn  as integer   no-undo.
define variable offsetOut as integer   no-undo.

define variable fileName  as character no-undo format "x(30)".
define variable oldString as character no-undo format "x(30)".
define variable newString as character no-undo format "x(30)".

define stream s.
define stream r.

update
  fileName  skip
  oldString skip
  newString skip
 with
  side-labels
.

do on endkey undo, leave while true:

  input  stream s from value( fileName ).
  seek stream s to offsetIn.

  inLine = ?.

  import stream s unformatted inLine.

  if inLine = ? then
    do:
      message "EOF wasn't trapped!?!".
      leave.
    end.

  assign
    txtLength = length( inLine )
    offsetOut = seek( s )
    offsetOut = offsetOut - txtLength - 1
    outLine   = replace( inLine, oldString, newString )
  .

  input stream s close.
  output stream r to value( fileName ) append.
  seek stream r to offsetOut.
  put stream r unformatted outLine skip.
  offsetIn = seek( r ).
  output stream r close.

end.
 

tamhas

ProgressTalk.com Sponsor
Note that, in addition to tools like sed, tools like touch will help control dates.
 

TomBascom

Curmudgeon
I may be wrong but "c:\abc.txt" gives me the idea that our original poster is working with Windows. (Which is why I have the EOF got skipped code in there...)
 

TomBascom

Curmudgeon
I suppose if I'm going to be a smart-alec about windows I ought to test under windows too :(

Some minor changes:

Code:
/* sed.p
 */

define variable inLine    as character no-undo.
define variable outLine   as character no-undo.
define variable txtLength as integer   no-undo.
define variable offsetIn  as integer   no-undo.
define variable offsetOut as integer   no-undo.

define variable fileName  as character no-undo format "x(30)".
define variable oldString as character no-undo format "x(30)".
define variable newString as character no-undo format "x(30)".

define stream s.
define stream r.

update
  fileName  skip
  oldString skip
  newString skip
 with
  side-labels
.

do on endkey undo, leave while true:

  input  stream s from value( fileName ).
  seek stream s to offsetIn.

  inLine = ?.

  import stream s unformatted inLine.

  if inLine = ? then
    do:
      message "EOF wasn't trapped!?!".
      leave.
    end.

  assign
    txtLength = length( inLine )
    offsetOut = seek( s )
    offsetOut = offsetOut - txtLength - 2
    outLine   = replace( inLine, oldString, newString )
  .

  input stream s close.
  output stream r to value( fileName ) append.
  seek stream r to offsetOut.
  put stream r unformatted outLine skip.
  if txtLength = 0 then put stream r unformatted skip(1).
  offsetIn = seek( r ).
  output stream r close.

end.

DOS/Windows newline is CR+LF vs LF on UNIX so a 2 character adjustment to the offset is needed.
 

vinod_home

Member
what if you change the information and put it into a new file. Then open the original in append mode, seek the first line and then replace the contents.

HTH
 

tamhas

ProgressTalk.com Sponsor
On might note that changing the file in situ is dangerous, so filtering to a new file and then replacing is much safer.

One also has to wonder why the date should remain the same. Seems a bit like "Psst, don't audit trail this change".
 

shireeshn

Member
thanks all

but tom iam not asking for fun. The code which u gave working fine for me. can i go head with it, as tamhas said it is dangerous, iam little bit scared abt it. boz i have to change the lot of files ( source code file).

if i go head , how can find something went wrong . boz my files are very very importent.

your replay give me idea about reading and writing into the same file. good one tom.:)

thanks in advance.
 

ron

Member
As a matter of interest ... are you making the same change to each source file? Are you always changing one particular string of characters into another one?
 

ron

Member
You don't happen to have Perl on your Windows machine, do you?

It's a very easy job for Perl (ie, all files at the same time).

You can download Perl for free from http://strawberryperl.com/

Get version 5.10.0.6. It will come down as as .msi file. Just double click it to install it.

I can give you the code to do your job in Perl if you like.

Ron.
 

TomBascom

Curmudgeon
If you want something that is more robust than "just for fun" I'm available for hire ;)

Otherwise backup your files and test the code thoroughly if you're going to use what I've posted.
 

shireeshn

Member
i have two problems, can any one help me in this.

1) when replace string length differs with old string (oldString = "tom" newString = "jonee" where old string length = 3 and new string length = 5)
2) when blank space encounter (next line)
 

TomBascom

Curmudgeon
The blank line issue is corrected in the 2nd version of the code.

Differing string lengths are an exercise for the student. Or a consulting engagement. It's way more work than I'm willing to go to just for kicks.

Of course all of this is much simpler if you'd eliminate the "edit in place" requirement. Hopefully I'm wrong but the only reason that I can think of for that is that you're trying to skirt someone's copy protection or license restrictions.
 
Top