Hello,

I am new to the perl programming language and I have a question. I was wondering if it was possible to implement an array of strings that contains video files?

I also wanted to know if it was possible to create state machines using the perl programming language? Thank you in advance.

On a side note: I have looked online about state machines but have only seen examples written in c code and not perl. I also know how to create string arrays, I'm just confused on how I would create an array of strings that contains video files.

To clarify, I would like to know how to create an array that contains files. For example, say you have a folder with 8 files. I would like to place those 8 files into array[0] through array[7].

Also is there a way to set your array to a certain file size? thank you in advance.

Hello,

I am new to the perl programming language and I have a question. I was wondering if it was possible to implement an array of strings that contains video files?

I also wanted to know if it was possible to create state machines using the perl programming language? Thank you in advance.

On a side note: I have looked online about state machines but have only seen examples written in c code and not perl. I also know how to create string arrays, I'm just confused on how I would create an array of strings that contains video files.

My platform is Windows and there happen to be some files whose filenames end in '.txt' in the current directory. Some of them are larger than 3,000 bytes.

#!/usr/bin/perl -w
use strict;
#Get list of filenames ending in .txt, test for file (not directory) attribute
# and test that file size is greater than 3000
#Put list of filenames into an array
my @files = grep { -f and (-s > 3000) } glob( '*.txt' );

#Print each filename in array, separated by newline
foreach my $f (@files) {
    my $filesize = -s $f;
    printf "%-25s size is %15d \n", ($f, $filesize);
}

As for state machines, I think that pertains to object-oriented programming in Perl, which I haven't learned yet. Are you looking for something like what is discussed in this page about Perl design patterns ?

Thank you very much. I looked up grep -f and glob and the code that you provided makes sense. Is there a way to create the array @files a certain size?

Also the information about perl design patterns is exactly what I was looking for. I'll do more research about that topic to see if I can find examples.

My platform is Windows and there happen to be some files whose filenames end in '.txt' in the current directory. Some of them are larger than 3,000 bytes.

#!/usr/bin/perl -w
use strict;
#Get list of filenames ending in .txt, test for file (not directory) attribute
# and test that file size is greater than 3000
#Put list of filenames into an array
my @files = grep { -f and (-s > 3000) } glob( '*.txt' );

#Print each filename in array, separated by newline
foreach my $f (@files) {
    my $filesize = -s $f;
    printf "%-25s size is %15d \n", ($f, $filesize);
}

As for state machines, I think that pertains to object-oriented programming in Perl, which I haven't learned yet. Are you looking for something like what is discussed in this page about Perl design patterns ?

Also is there a way to set your array to a certain file size? thank you in advance.

Is there a way to create the array @files a certain size?

Sorry, I don't understand this part of your question. Do you mean can you make an array of only 8 files, for example, when the my @files = grep { -f and (-s > 3000) } glob( '*.txt' ); returns an array of more than 8 files? Or do you mean the array should contain only filenames of files that are less than or equal to a certain size?

Here is an example of both:

#!/usr/bin/perl -w
use strict;
use List::Util qw(min);
#Get list of filenames ending in .txt, test for file (not directory) attribute
# and test that file size is less than or equal to 3000
#Put list of filenames into an array
my @files = grep { -f and (-s $_ <= 3000) } glob( '*.*' );

#Print each filename in array, separated by newline
foreach my $f (@files) {
    my $filesize = -s $f;
    #printf "%-25s size is %15d \n", ($f, $filesize); If you want to format what you print
    print "$f size is:   $filesize\n"
}

#To limit the size of an array, take a slice of original array:
my $size_of_original_array = @files; #Number of elements in array

my @NoMoreThanEightFiles = @files[0..(min $size_of_original_array, 8) - 1];

#Print each filename in array, separated by newline
print "\nPrinting no more than eight filenames:\n";
foreach my $f (@NoMoreThanEightFiles) {
    my $filesize = -s $f;
    #printf "%-25s size is %15d \n", ($f, $filesize); If you want to format what you print
    print "$f size is:   $filesize\n"
}

Ah, so you have to first assign the files to an array and then adjust that array to limit the number of files, interesting. Thank you very much for your help, the sample code was very helpful in understanding how arrays with files work.

Today I googled some more and found another way to get a list of files using the opendir and readdir commands. Unlike glob which only works for the current directory, these commands require you to specify a directory. This means to get the file size you need to specify the full path with the filename. The advantage of the opendir and readdir is that you use a loop to push each filename into the array, and so you can have a counter and stop adding to your array when you reach your limit. This way you don't have to adjust your array afterwards.

#!/usr/bin/perl -w
use strict;
my $directory = 'C:\Users\David\Documents';
my ($filename, $pathandfilename, @files);
my ($count, $limit) = (0, 8);
opendir DIR, $directory or die $!;
while ($filename = readdir(DIR)) {
    $pathandfilename = "$directory\\$filename";
    push @files, $pathandfilename if -s $pathandfilename <= 10000 and -f $pathandfilename and $count++ < $limit;
}
#Print each filename (including path) in array, followed by file size
foreach my $f (@files) {
    my $filesize = -s $f;
    print "$f size is: $filesize\n";
}

Ok, so I ran the code and I have a slight issue. The print statement in the foreach loop wasn't printing. So, to debug, I put a few print statements in, and noticed that count is never incremented (it stays at 0).

I think this is because "++" seems to be recognized as a string instead of an increment (because my text editor colors it pink which is the color for strings). It seems like the -s argument is causing the change in text colors.

Do you know why this is happening by any chance?

Since the script worked for me and not for you we probably have different operating systems. I suspect the troublesome statement could be $pathandfilename = "$directory\\$filename"; . That assumes that putting a backslash (actually an 'escaped' backslash -- that's why there are two of them) between the directory and the filename results in a valid path. That is true for Windows/DOS systems but not for others. Try replacing $pathandfilename = "$directory\\$filename"; by $pathandfilename = "$directory/$filename"; and please let me know if it works.

This article has been dead for over six months. Start a new discussion instead.