drewrockshard
drewrockshard

Reputation: 2071

Perl: Append to file and get new line count

Quick question, and I'm sure it's something I'm doing completely wrong with variables, however, here is the issue.

Code first:

#!/usr/bin/perl
use strict;
use warnings;

my $File = "file.txt";
my $CurrentLinesCount = `wc -l < $File` or die "wc failed: $?";
chomp($CurrentLinesCount);

sub GetStatistics() {
    if (-d $dir) {
            print "Current Lines In File: $CurrentLinesCount\n";
    }
    else { 
            exit;
    }
}
sub EditFile() {
    my $editfile = $File;
    my $text = "1234\n12345\n234324\n2342\n2343";
    open(MYFILE,">>$editfile") || die("Cannot Open File");
    print MYFILE "$text";
    close(MYFILE);
    sleep 5;
}

## MAIN
GetStatistics();
EditFile();
GetStatistics();

This is the output I get:

Current Lines In File: 258
Current Lines In File: 258

I verified that the file is being written and appended to. Can someone point me in the correct direction on how to have a variable set, updated, and then called again properly?

Upvotes: 0

Views: 969

Answers (4)

outis
outis

Reputation: 77400

As an optimization, you can count how many lines you added rather than recounting the whole file (unless another process may also be writing to the file).

use strict;
use warnings;
use FileHandle;
use IPC::Open2;

our $CurrentLinesCount;
our $file = "file.txt";

sub CountLines {
    my $File = shift;
    my $CurrentLinesCount = `wc -l < $File` or die "wc failed: $?";
    $CurrentLinesCount =~ s/\s+//g;
    return $CurrentLinesCount;
}

sub ShowStatistics {
    my $file = shift;
    if (-f $file) {
        print "Current Lines In File: $CurrentLinesCount\n";
    } else { 
        exit;
    }
}

sub EditFile {
    my $editfile = shift;
    my $sleeptime = shift || 5;
    my $text = "1234\n12345\n234324\n2342\n2343";
    open(MYFILE,">>$editfile") || die("Cannot Open File");
    print MYFILE "$text";
    close(MYFILE);
    # Look here:
    my $pid = open2(*Reader, *Writer, "wc -l" );
    print Writer $text;
    close Writer;
    $CurrentLinesCount += <Reader>;
    sleep $sleeptime;
}

$CurrentLinesCount = CountLines($file);
ShowStatistics($file);
# EditFile updates $CurrentLinesCount
EditFile($file, 2);
ShowStatistics($file);

Still one too many globals for my taste, but I suppose this isn't a program of consequence. On the other hand, globals can be habit forming.

Note that wc doesn't count anything after the final "\n" when counting lines (it views "\n" as a line terminator). If you want to view "\n" as a line separator and count those trailing characters as a line, you'll need an alternate method of counting lines.

Upvotes: 0

mguillech
mguillech

Reputation: 336

I would probably move the code block

my $CurrentLinesCount = `wc -l < $File` or die "wc failed: $?";
chomp($CurrentLinesCount);

to the GetStatistics subroutine, so the variable is updated whenever you call your sub.

Upvotes: 0

ysth
ysth

Reputation: 98388

You call subs, not variables.

Try:

sub CurrentLinesCount {
    my $CurrentLinesCount = `wc -l < $File` or die "wc failed: $?";
    chomp($CurrentLinesCount);
    return $CurrentLinesCount;
}

...

    print "Current Lines In File: ", CurrentLinesCount(), "\n";

Upvotes: 2

CanSpice
CanSpice

Reputation: 35788

You're only doing the call to wc once. Thus you're setting the value of $CurrentLinesCount once, and you get the same number when you print it twice.

You'll have to redo the

$CurrentLinesCount = `wc -l < $File` or die "wc failed: $?";

line after you append to the file.

Edit: Or put that line in the GetStatistics function, which would probably be a better place for it.

Upvotes: 1

Related Questions