开发者

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,">>$editfi开发者_JAVA技巧le") || 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?


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";


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜