Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Deleting a line out of text file

by Anonymous Monk
on Aug 13, 2003 at 15:29 UTC ( [id://283580]=perlquestion: print w/replies, xml ) Need Help??

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

I am opening a file and want to find if something exists and if so then delete that line. So if I get a hit on the number 019 in my file I need to delete the line it is on. file.txt:
234 324 2323 232 344 1213 019 232 343 #delete this line 344 343 324
My attempt at reading it but how would I delete the line with 019 in it??
$fil = 'file.txt'; open(DATA, "$fil") || die "cant open: $!\n"; foreach $line (<DATA>) { if($line =~ /$var/gi) #in this case the variable would be 019 { print "data exists now need to delete it"; s/$var//; #this is not working } } close(DATA);

Replies are listed 'Best First'.
Re: Deleting a line out of text file
by Abigail-II (Bishop) on Aug 13, 2003 at 15:34 UTC
    $ perl -ni -we 'print unless /019/' file.txt

    Abigail

      For those not familiar with all the command line options you can specify in a perl one-liner, do
      perldoc perlrun
      at a comand prompt.

      HTH.
Re: Deleting a line out of text file
by pzbagel (Chaplain) on Aug 13, 2003 at 15:33 UTC

    Your problem is that you cannot just edit a file in place. All you are changing is the line which is in a variable in memory, it never gets to the disk. The most concise way to do this is to open the file, and then print out all the lines except the one you don't want. Then you can redirect the output to another file. Also, some of perl's command-line arguments can help you accomplish that:

    #!/usr/bin/perl -nw use strict print unless /$var/i; # or a perl one-liner perl -i.bak -nwe 'print unless /019/i' <file>

    HTH

    Addendum: RE: Abigail's comments: Added the -e switch. And the 'gi' is just following the orginal poster since 019 may not be the only data (s)he is looking for, didn't want the confuse the issue if they plugged in some other data and it was missing. I suppose the 'g' is superfluous in this case, guess you can safely remove that one.

      Why the /gi? Also, you need a -e switch.

      Abigail

      Thanks to all. Here is the direction I wanted to go but this wipes out my whole file and just keeps the line I changed: Can someone tell me how I can fix this?
      my $fil = 'file.txt'; open(DATA, "$fil") || die "Can not open: $!\n"; my @dat = (<DATA>); close(DATA); open(DATA, ">$fil") || die "cant write: $!\n"; foreach (@dat) { if($_ =~ /number/) { s/number/NEWWORD/; print DATA $_; } } close(DATA);

        You need to print out all the other lines also.

        If you want to edit a line and leave it in the file then just get rid of the if.

        ... foreach (@dat) { s/number/NEWWORD/; print DATA $_; } close(DATA);

        This will change the lines that need changing and print everything into the file.

        There is another risk with this method that if the program dies before getting the file printed back out your original file which was erased on the second open will not have the complete data. This is what the backup options cover you against.

        This will do the translation and leaves a backup file in this case named file.txt.bak.

        perl -pi.bak -e 's/number/NEWWORD/;' file.txt

        The -p says to print every line, the -i.bak says make a backup file by adding .bak to the input file name, -e says to run the next argument as a perl script. The substitute only happens if the pattern matched so there is no need for an if unless you want to locate one pattern and then replace another pattern with yet a different replacement.

      ...you cannot just edit a file in place...

      This has been coming up a lot recently. See Tie::File:

      "Tie::File" represents a regular text file as a Perl array. Each element in the array corresponds to a record in the file. The first line of the file is element 0 of the array; the second line is element 1, and so on. The file is not loaded into memory, so this will work even for gigantic files. Changes to the array are reflected in the file immediately.

      For an example of changing a file in place using Tie::File, see this node and this node.


      cp
      ----
      "Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic."

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://283580]
Approved by halley
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-20 04:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found