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

I am perl bginner (but i guess logic is same for all programming languages like C++ and C in my case its perl).

What i want to achieve ?

I have a text file i read that file which contains different IPaddress Time in each line and when i find a particular Time then i delete that line.

What is the problem ?

The problem is when i open a file and check for time (to see that is this the particular time i am looking for to delete this line) then it need to read that file (I mean '<' operation) but when i have to delete that particular line after finding that correct time i need to do write operation (I mean this '>' operation). Now when i try to achieve this i use this code (which will surely not work as the file is opened in read mode we cannot delete (i mean write to it)):

open my $fhi, '<', 'C:\shekhar_Axestrack_Intern\WindowCreation\ListOf +IpAdress.txt', or die "Could not open file $!"; while (my $line = <$fhi>) { ## Doing some operation using $fhi in read mode if($Time >'33') { $fhi->autoflush; #flush the line if time is greater than 33 +hours, whereas all other lines which do not folow the condition are s +till present in file. } } close $fhi;

How to delete that particular line in text file (after some manupulation of time ?)

EDIT:

open my $fhi, '<', 'C:\shekhar_Axestrack_Intern\WindowCreation\ListOfI +pAdress.txt', or die "Could not open file $!"; open my $fho, '>', 'C:\shekhar_Axestrack_Intern\WindowCreation\Lis +tOfIpAdress.txt', or die "Could not open file $!"; while (my $line = <$fhi>) { //Here i write the code to get the time from text file in ech li +ne and below i check in if condition if that exceed 34 hours then flu +sh that line if($Time >'34') { $fhi->autoflush; } print $fho; } close $fhi;

But it deletes all my file ListOfIpAdress.txt whereas i just want to delete only those lines where time > 34

  • Comment on How to delete a particular line in a text file after some operation on that text file at the same time
  • Select or Download Code

Replies are listed 'Best First'.
Re: How to delete a particular line in a text file after some operation on that text file at the same time
by Athanasius (Cardinal) on Jan 18, 2015 at 03:31 UTC

    Hello ppp,

    Please see the entry “How do I change, delete, or insert a line in a file, or append to the beginning of a file?” in perlfaq5. Note the following:

    The basic idea of inserting, changing, or deleting a line from a text file involves reading and printing the file to the point you want to make the change, making the change, then reading and printing the rest of the file. Perl doesn't provide random access to lines...

    Once the new file has been written successfully, delete the original and rename the new file using either the builtin rename function or the move function from File::Copy.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Hii, Thanks for the answer. please see the EDIT part in my answer i tried it but it deltes all the text file.
        while (my $line = <$fhi>) { //Here i write the code to get the time from text file in ech li +ne and below i check in if condition if that exceed 34 hours then flu +sh that line if($Time >'34') { $fhi->autoflush; } print $fho; }

        The autoflush function isn’t going to help you here. You need logic like this (untested):

        while (my $line = <$fhi>) { # get $time print $fho $line unless $time > 34; }

        That is: print to the output file only those lines which pass the test, and silently ignore those which don’t. And note that your statement: print $fho; needs to be changed to print $fho $line; in order to work correctly here.

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: How to delete a particular line in a text file after some operation on that text file at the same time
by GotToBTru (Prior) on Jan 18, 2015 at 05:53 UTC

    I suggest you use module Tie::File. It allows you to treat the file just like an array, so adding, editing and removing lines is as easy as array operations.

    use strict; use warnings; use Tie::File; tie my @lines, 'Tie::File, 'ListOfIpAdress.txt' or die "$!"; # define sub F such that it returns 0 if Time > 34, 1 otherwise @lines = grep { F($_) } @lines; untie @lines;
    Dum Spiro Spero
      Hii, Thanks , i tried thsi but doesnt change anything in my file.
      my $file = 'C:\shekhar_Axestrack_Intern\WindowCreation\ListOfIpAdress. +txt'; tie my @lines, 'Tie::File', $file or die "can't update $file: $!"; # define sub Fun such that it returns 0 if Time > 34, 1 otherwise @lines = grep { Fun($_) } @lines; untie @lines; sub Fun { my($line) = @_; #I do manupulation on this line to get time fr +om string # print $fho $line unless $div > 36; if( $time > 37) {return 0;} else{ return 1;} }

        You need to post a small self-contained program to demonstrate your problem. That way, we can reproduce your problem, verify that the output is wrong, and then offer ways to fix it. Unfortunately, your example code above refers to $time yet that variable is not defined in your posted code.

        Oh, and make sure that all self-contained code samples you post start with:

        use strict; use warnings;

        Update: See also SSCCE (Short, Self Contained, Correct (Compilable) Example).

        I assume then that Fun() never returns 0.

        sub Fun { $a = shift; return $a > 0 ? 1 : 0 } @a = (1,2,-3,4,-5,99); printf "%d, ",$_ for grep {Fun($_)} @a;

        Output:

        1, 2, 4, 99

        Updated to add simple example

        Dum Spiro Spero
Re: How to delete a particular line in a text file after some operation on that text file at the same time
by BillKSmith (Monsignor) on Jan 18, 2015 at 04:56 UTC
    The solution may be easier if you think of the problem as "Copy all the lines which do not contain the correct time.".
    Bill
Re: How to delete a particular line in a text file after some operation on that text file at the same time
by locked_user sundialsvc4 (Abbot) on Jan 19, 2015 at 02:58 UTC

    I always recommend that you plan the program so that it can be re-run successfully if for any reason it does not succeed.   This means being “non-destructive” of the program’s inputs.   Instead of actually overwriting the input file to “remove” certain records, the program produces, as one of its several outputs, a new version of its input-file which “omits” certain records.   Then, if everything goes according to plan, that output-file becomes the input-file that will be used in the next run ... but the previous input-file also is still there.   (And maybe several of them, logrotate style.)

    This is a very good strategy for a lot of good reasons:   for one thing, you can easily diff the two files (“before” and “after”) to be certain what it actually did.   You can objectively analyze the situation, and you can reliably do a re-run if necessary.

    (If you really do need to update a file in-place, I suggest that you use a database-file format such as the ubiquitous SQLite ... but, even then, that you do not actually delete the successfully-processed records right away.   Instead, “soft-delete” them in some way, such as by writing a timestamp to a field that will be NULL for any records that are yet-to-be-processed.   Give yourself a source of history, as well as something that can be reversed should the need arise.   “Ka-ka occurs ...”)