Re: Rolling variable
by stevieb (Canon) on Jul 30, 2015 at 13:59 UTC
|
You can use Tie::File to store your data in a file, and use push and shift per Ratazong's suggestion on the array which modifies the file live-time:
use Tie::File;
tie my @file, 'Tie::File', 'file.txt' or die $!;
shift @file if @file == 8;
...
push @file, 'new data';
...
untie @file;
Then, use cron to run your script every hour, and for any other external processing, just pull the data out of the 'file.txt' file.
-stevieb | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Rolling variable
by Ratazong (Monsignor) on Jul 30, 2015 at 13:43 UTC
|
Hi artperl
For 8 integer-values an array seems to be the easiest (and efficient enough). Please check push for appending a value at the end and shift to remove the first element.
HTH, Rata
| [reply] [Watch: Dir/Any] |
Re: Rolling variable
by fishmonger (Chaplain) on Jul 30, 2015 at 14:02 UTC
|
I would need to keep that counts somewhere for another calculation but I would like to keep only the last 8 counts
If the script is being executed each hour (presumably via a cron job) and you need to retain/use the array from the prior run, then you might want to look at using the Storable module to store/retrieve the array.
Update:
Just in case you weren't sure what I was suggesting, here's a short test script example.
use strict;
use warnings;
use Storable qw(store retrieve);
my @cnt = -e 'file_count' ? @{ retrieve('file_count') } : ('') x 8;
my $fcount;
$fcount++ for glob('*');
unshift @cnt}, $fcount;
pop @cnt;
store(\@cnt, 'file_count');
Edit: changed the array reference $cnt_aref to a plain array @cnt | [reply] [Watch: Dir/Any] [d/l] |
Re: Rolling variable (Update:prime the counts file first!)
by BrowserUk (Patriarch) on Jul 30, 2015 at 16:13 UTC
|
Add this one liner to your scheduler to run hourly, and the last 8 counts will be found in the file counts:
perl -i'*' -anle"@f=<c:/test/*>; shift @F; push @F, scalar @f; print j
+oin ' ', @F;" counts
Update:You do have to prime the counts file: echo 0 0 0 0 0 0 0 0 > counts
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
The first time you run this you will get an error because the file counts doesn't exist.
Also, do you mean to have both @F and @f?
Running this on my machine adds nothing to the file.
$ pwd
/Users/nick/monks
$ ls | wc -l
39
$ perl -i'*' -anle"@f=</Users/nick/monks/*>; shift @F; push @F, scalar
+ @f; print join ' ', @F;" counts
$ cat counts
$
The way forward always starts with a minimal test.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
Does not work as expected in my test.
(1) It assumes that the counts file already exists, which it may not.
(2) If the file is there but empty, it doesn't add anything to the file.
(3) It changes all lines to the same value.
| [reply] [Watch: Dir/Any] |
Re: Rolling variable
by james28909 (Deacon) on Jul 30, 2015 at 13:50 UTC
|
use strict;
use warnings;
my @array = qw(file1 file2 file3 file4 file5 file6 file7 file8 file9);
+ #array with file names
my @reversed_array = reverse @array; #reverse @array so reading from t
+he last element
my @files; #this array will contain 8 file names once done
for(0 .. 7 ){ #8 iterations
push @files, $reversed_array[$_];
}
#print "$_\n" for reverse @files;
print "$_\n" for @files;
| [reply] [Watch: Dir/Any] [d/l] |
|
Hi James, Rata,
Thanks for the inputs. However, I thin k this will work in a single run of the script (please correct me if I'm wrong). Since I would like to monitor in an hourly basis, that means I will call the perl script to run thru a cron. So I was thinking to save the counts in a file.
| [reply] [Watch: Dir/Any] |
|
you could easily adopt this into a script and have it run every hour. call it from your main script. spit any output to files if needed. go ahead modify it as needed :)))
| [reply] [Watch: Dir/Any] |
|
use strict;
use warnings;
my @file_array = qw(file1 file2 file3 file4 file5 file6 file7 file8 fi
+le9);
my @reversed_file_array = reverse @file_array;
my @files;
while (1) {
for ( 0 .. 7 ) {
push @files, $reversed_file_array[$_];
}
print "$_\n" for @files;
undef @file_array;
undef @files;
sleep 2; #or sleep 3600 for 1 hour
}
If you dont undef @files then it will keep a list of the filenames. You can comment it out to see if you need to undef it or not. To me though, if you have already did operations on the files in @files, then there is no need to save a list.
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
Re: Rolling variable
by Anonymous Monk on Jul 31, 2015 at 00:37 UTC
|
In simple terms, you will have to capture the 8 most-recent observations in some sort of list, to which you will push the latest entries and then use (perldata array slices) to capture the most-recent ones. "How you persist those values" is entirely up to you. | [reply] [Watch: Dir/Any] |
Re: Rolling variable
by M4 (Novice) on Jul 31, 2015 at 06:53 UTC
|
Your question is inconsistent. You want to keep a filecount (ls | wc -l) and record the count (>/some/dir/some.file). That is one count. Then you want to keep the 8 most recent counts? You only have one!
Having said that, whatever you really mean, it sounds like something a simple shell script is better suited for than Perl, but not knowing the exact requirements, one cannot say definitely. | [reply] [Watch: Dir/Any] |