in reply to create array of empty files and then match filenames

The following code creates a list of all files in your current directory which have a number in the name (such as 1.txt, 22, file345.doc):
use warnings; use strict; my @emptyfiles = grep { /\d/ } grep { -f } glob '*';
To restrict to file names which only have digits (such as 22, 4, 99999, 0):
my @emptyfiles = grep { /^\d+$/ } grep { -f } glob '*';
If that is not what you are looking for, you need to be more specific.

Replies are listed 'Best First'.
Re^2: create array of empty files and then match filenames
by afoken (Chancellor) on Jan 07, 2016 at 20:48 UTC
    my @emptyfiles = grep { /\d/ } grep { -f } glob '*';

    Why two greps?

    I don't think it makes a big difference for a small set of files, but this solution runs through two loops (implicitly in grep) where one loop is sufficient:

    my @files = grep { -f && /\d/ } glob '*';

    Also, -f hides a system call (stat), which is quite expensive. Swapping the order avoids the system call for all directory entires whose names do not match the regular expression:

    my @files = grep { /\d/ && -f } glob '*';

    Or, if you want to keep the two greps:

    my @files = grep { -f } grep { /\d/ } glob '*';

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re^2: create array of empty files and then match filenames
by angela2 (Sexton) on Jan 07, 2016 at 16:01 UTC

    Hi!

    This works! I also tried it against a few files with numbers in their filename but that are not empty, and it's still successful, only finding the empty ones, so my choice for using if -z was correct (I hope).

    Can you tell me what {grep -f} and {glob '*'} do? Also, can you tell me a couple of things that were wrong with my code??? I assume I have many mistakes but if you could mention one or two it'd still be good for me

    Thank you very very much

      my @emptyfiles = grep { /^\d+$/ } grep { -f } glob '*';

      Let's look at this right to left. glob '*' returns a list of files, the same list you'd get if you use * as the argument to an ls or dir command, except it's just the file names, not the dates, sizes, etc that those commands also return. This list will be the input to the grep command.

      my @emptyfiles = grep { /^\d+$/ } grep { -f } [ 1 temp.dat testdirecto +ry 10 resume.wd ]

      grep { something } list returns the list that results by applying the something as a test. If it passes, it is included in the return. glob will return both file and directory names in its list. Applying the -f test will remove the directories. The middle grep returns a list also.

      my @emptyfiles = grep { /^\d+$/ } [1 temp.dat 10 resume.wd ]

      we can use another grep to further filter the list to just the files we want, those whose name consists of 1 or more digits, and nothing else.

      my @emptyfiles = [1 10]
      But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

        Oh thanks! I read loads of stuff on perldoc and still couldn't work out I had to read it from right to left to decrypt it. Thank you so much, great explanation.
      Can you tell me what {grep -f} and {glob '*'} do?
      If you have the "Function Nodelet" displayed, there are links to these Perl built-in functions. Otherwise... glob, grep
        Oh sorry, I read these two pages but for example I didn't find "grep -f" in them so I thought they weren't complete. Is -f just the general -f option?
      Ooops sorry I missed your updated post. I know I'm annoying but can you tell me why the second line only matches file names which only have digits? Is it this +$ thing? I recognise the ^, this means "that starts with", if I understood correctly.