Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

In-place file manipulation

by ibanix (Hermit)
on Apr 30, 2003 at 14:53 UTC ( [id://254316]=perlquestion: print w/replies, xml ) Need Help??

ibanix has asked for the wisdom of the Perl Monks concerning the following question:

Hello my monkish friends,

I'm trying to find a simple and efficent way to:

1) Read a line from a file
1b) Do stuff....
2) Edit that line
3) Write it back to file in the same location (overwrite)
4) Repeat for next line, etc.


I know I can  open(my $fh, "+<< $file") to open my file in read/append mode. I also know that I can use seek() to jump around in the file, though my actual use of it hasn't been much.

Any advice here?

Thanks,
ibanix

$ echo '$0 & $0 &' > foo; chmod a+x foo; foo;

Replies are listed 'Best First'.
Re: In-place file manipulation
by Corion (Patriarch) on Apr 30, 2003 at 15:03 UTC

    The Tie::File module has an excellent way of treating a file like an array, and the synopsis provides all you need to know for basic usage :

    # This file documents Tie::File version 0.93 tie @array, 'Tie::File', filename or die ...; for (@array) { s/PERL/Perl/g; # Replace PERL with Perl everywhere in th +e file }
    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
Re: In-place file manipulation
by broquaint (Abbot) on Apr 30, 2003 at 14:58 UTC
    A sublime example for the use of the -i switch when using perl from the command line. See. perlrun for info on this marvellous switch (best used in conjunction with -p and -e).
    HTH

    _________
    broquaint

      I use this one all the time. A quick example of broquaint's suggested technique (from the command line), to replace all capitalization permutations of the word 'perl' to 'Perl' in file perl.pl, and store the original in perl.pl.bak:

      perl -pi.bak -e 's/\bperl\b/Perl/gi' perl.pl
Re: In-place file manipulation
by halley (Prior) on Apr 30, 2003 at 15:53 UTC

    The (-i) switch is so easy for adjusting TEXT files. I use this so often, that in my login script, I set an alias for pie=perl -p -i~ -e. Easy as pie.

      pie s/2002/2003/g *.html

    However, -i really doesn't edit "in place," but it does a good simulation of it. It creates a new file and moves the old file to a backup extension. You may have problems with access control lists (ACLs) on some network file system implementations. Experiment.

    The '+' modes for the open() function are designed for fixed-record DATA updating. Note both examples in (perldoc -f open) refer to database files. Not that you couldn't use the functions for text files, but it would be a horrible and unnecessary tangle of seek(), tell() and caching to avoid overwriting parts of the next line before it is read. Not to mention further complications for newline conversion entanglement.

    I wish the docs were more clear about this, to avoid this recurring question.

    --
    [ e d @ h a l l e y . c c ]

Re: In-place file manipulation
by nite_man (Deacon) on Apr 30, 2003 at 15:39 UTC
    Maybe File::Data will be usefull for you:
    use File::Data; use strict; use File::Data; my $o_dat = File::Data->new('./t/example'); $o_dat->write("complete file contents\n"); $o_dat->prepend("first line\n"); # line 0 $o_dat->append("original second (last) line\n"); $o_dat->insert(2, "new second line\n"); # inc. zero! $o_dat->replace('line', 'LINE'); print $o_dat->READ;
          
    --------------------------------
    SV* sv_bless(SV* sv, HV* stash);
    
Re: In-place file manipulation
by AcidHawk (Vicar) on Apr 30, 2003 at 15:01 UTC

    I looked at PerlFaq5 and modified that code a little.

    -----
    Of all the things I've lost in my life, its my mind I miss the most.
Re: In-place file manipulation- Played!
by benn (Vicar) on May 01, 2003 at 00:12 UTC
    Surely - this was a reverse golf game? We start off well under par on the green with -i, through the rough with a couple of modules, back down the hill with an alias, round the 20-liner dog-leg and end up at the clubhouse with a dedicated however-many-thousand-line text editor solution. Good show! :)
Re: In-place file manipulation
by perlplexer (Hermit) on Apr 30, 2003 at 15:08 UTC
    Do records in your file have the same length? If so, the best approach is to go with read/print/seek or sysread/syswrite/sysseek.
    If record size may change after some of the fields in it are modified, you may find that having a temp file is easier than having to write a sub for shifting data within the file.

    --perlplexer
Re: In-place file manipulation
by bobdeath (Scribe) on Apr 30, 2003 at 14:58 UTC
    I usually just read from the file, modify, and write to a new file, then override the first file with the second when I am done. Probably not the prettiest solution, but it gets the job done.
Re: In-place file manipulation
by atnonis (Monk) on Apr 30, 2003 at 16:22 UTC
    Hello this is one way to do it! it works for me
    #!/usr/bin/perl -w use strict; die "usage: $0 <file> <search pattern> <replace pattern>", unless @ARGV == 3; my $searchFile = $ARGV[0]; my $searchPattern = $ARGV[1]; my $replacePattern = $ARGV[2]; my $tempFile = 'tmp$$'; open FILE, $searchFile #opens file in read-only mode or die "Cannot open $searchFile in read-only mode. $!\n"; open TMP, '>'.$tempFile or die "Cannot create temp file. $!\n"; while (<FILE>) { chomp; if (/$searchPattern/i) { print "Match found...replacing at line $.\n"; $_ =~ s/$searchPattern/$replacePattern/i; print TMP $_."\n"; }else { print TMP $_."\n" } } close FILE; close TMP; unlink $searchFile; rename $tempFile, $searchFile;


    Antonis!
Re: In-place file manipulation
by LameNerd (Hermit) on Apr 30, 2003 at 16:30 UTC
    Why not do something like this?
    $ your_script < your_input > your_output $ mv your_output your_input
      Because I'm on Win2k :-{

      Well, the real reason is that this isn't happening on the command line. But thanks anyway.

      Cheers,
      ibanix

      $ echo '$0 & $0 &' > foo; chmod a+x foo; foo;

        Ehm ... the only changes you'd have to make so that this does work under Win2k is to use move /Y<code> instead of <code>mv and to put perl before the script.pl.

        And you might even do it like this:

        perl script.pl < source.txt > result.txt && move /Y result.txt source. +txt
        Where the && means "execute the second command only if the first one did not return an error"

        Jenda
        Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
           -- Rick Osborne

        Edit by castaway: Closed small tag in signature

        Can you get away with installing cygwin?
Re: In-place file manipulation
by ibanix (Hermit) on Apr 30, 2003 at 21:15 UTC
    After looking at the options...

    I think I'm actually going to forget in-place manipulations on files and go directly to a module that will let me use a flat-file DB, and save myself the trouble. I'm just storing data -- the format won't matter greatly if I can read and store it consitently. I have not the need or the resources to run a full-scale SQL server.

    So, any suggestions on a good flat-file DB module?

    Thanks for everyone's suggestions!

    Cheers,
    ibanix

    $ echo '$0 & $0 &' > foo; chmod a+x foo; foo;
      I may be contradicting my previous post, but my problem is not your
      problem. There is a whole class of software that does what you are
      are trying to do. This class of software is called text editors. If you have the where-with-all (I don't) you might want to look into
      playing around with the source code of an open-source editors.

      Also why just mess with a flat file DB when there are open-source
      RDBMS you could use?

      Good luck with your project!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://254316]
Approved by pfaut
Front-paged by thelenm
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-25 09:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found