Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Delete specific lines from txt file.

by FredFredFred (Initiate)
on Aug 07, 2012 at 01:35 UTC ( #985862=perlquestion: print w/replies, xml ) Need Help??
FredFredFred has asked for the wisdom of the Perl Monks concerning the following question:

I am creating a program that keeps a record of people and their sports in a .txt file and I need to make an option to remove a player. When a new player is created, their first name, last name, sport, rank and 2 line breakers are written to the text file. I need code that asks for their first name and last name and then will delete the 5 lines of their information from the text file.

$first_name = <STDIN>; chomp $first_name; $last_name = <STDIN>; chomp $last_name;

It has to search the file for a line with both of those names and then delete that line, and the one above it and 3 below it. Thanks & good luck.

Replies are listed 'Best First'.
Re: Delete specific lines from txt file.
by roboticus (Chancellor) on Aug 07, 2012 at 02:41 UTC


    What part are you having trouble with? If it's actually removing the data from the file, then a typical method to do it is to write the data you want to keep to a new file. Then rename your data file to a backup version, and rename your new file with the original name.

    You're welcome, and good luck.


    When your only tool is a hammer, all problems look like your thumb.

      hmm, that sounds good, but I have no clue how to do it... Can you provide some code? Thanks


        # Discard every other line open FIN, 'INFILE' or die; open FOUT, '>' or die; my $cnt; while (<FIN>) { next if $cnt%2; print FOUT; } close FH; close FOUT; rename 'INFILE', 'INFILE.bak'; rename '', 'INFILE;


        When your only tool is a hammer, all problems look like your thumb.

Re: Delete specific lines from txt file.
by NetWallah (Canon) on Aug 07, 2012 at 03:38 UTC
    Here is the (untested) rest of your program.

    Please reference the perl documentation for constructs you have trouble with.

    $/="\n\n"; # Set the record separator to be 2 newli +nes my $sportfile=""; # Or whatever the file name is open (my $sport, "<", $sportfile) or die "Cannot open $sportfile : $!" +; while (defined <$sport>){ next if m/\b$first_name\b.+$last_name\b/; print; } close $sport;
    Output will print to STDOUT. This can be directed to a file.
    Update:Corrected "close $sportfile" to "close $sport;"

                 I hope life isn't a big joke, because I don't get it.

      This can be directed to a file.
      Just don't redirect it to the original file name. The first thing the OS would do is to truncate the original file, leaving no data for your text file to work with.


Re: Delete specific lines from txt file.
by GrandFather (Sage) on Aug 08, 2012 at 22:51 UTC

    You are dealing with a database, but making hard work of it. However Perl's DBI module along with DBD::CSV can turn your text based database file into something you can deal with as a "real" database. Consider:

    use warnings; use strict; use DBI; unlink 'sports.csv'; my $dbh = DBI->connect("dbi:CSV:f_ext=.csv") or die "Cannot connect: $DBI::errstr\n"; $dbh->do("CREATE TABLE sports (name TEXT, sport TEXT)"); my $sth = $dbh->prepare("INSERT INTO sports (name, sport) VALUES (?, ? +)"); $sth->execute_array({}, [qw(fred joe bob)], [qw(golf hockey luge)]); dumpTable($dbh); $dbh->do("DELETE FROM sports WHERE name = 'fred'"); print "\nDeleted fred\n"; dumpTable($dbh); print "\nCSV file contains:\n"; open my $fIn, '<', 'sports.csv'; print <$fIn>; close $fIn; sub dumpTable { my ($dbh) = @_; my $sql = 'SELECT name, sport FROM sports order by name'; for my $row (@{$dbh->selectall_arrayref($sql)}) { print "$row->[0]: $row->[1]\n"; } }


    bob: luge fred: golf joe: hockey Deleted fred bob: luge joe: hockey CSV file contains: name,sport joe,hockey bob,luge

    This of course uses a CSV file which may not be what you have, but with a little work you can probably use DBD::AnyData to manage your existing text based data in a very similar fashion.

    True laziness is hard work
Re: Delete specific lines from txt file.
by trizen (Hermit) on Aug 07, 2012 at 07:35 UTC
    See perldoc Tie::File.

    Here is a sample code:
    use strict; use warnings; use Tie::File; my $filename = '/path/to/file.txt'; my $firstname = 'John'; my $lastname = 'Watter'; tie my @array, 'Tie::File', $filename or die $!; for(my $i = 0; $i <= $#array; $i++){ if($array[$i] =~ /\b$firstname\b.+\b$lastname\b/){ splice(@array, --$i, 5); } } untie @array;
Re: Delete specific lines from txt file.
by pvaldes (Chaplain) on Aug 07, 2012 at 14:57 UTC

    Alternatively structure/dump the file as a hash (example below), forget all about duplicated blank lines and extra spaces and delete the hash-key provided as argument to the script. You could have a lot of troubles if some lines are duplicated, new fields are added later for new registers, or some fields are missing and you simply delete five untested lines here and there.

    my %sports= ( 'johnlazybones' => { 'firstname' => 'John', 'lastname' => 'lazybones', 'sport' => 'none known, never, ever', }, 'michaelflops' => { 'firstname' => 'Michael', 'lastname' => 'flops', 'sport' => 'sillonball', 'victories' => { '1' => '01-AUG-2012', '2' => '12-SEP-2011', }, }, );

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://985862]
Approved by rovf
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2018-06-25 01:06 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (126 votes). Check out past polls.