Newbie Perl question

C

christopher.prowse

Hi experts,

A quick (I hope) question...

I want to be able to verify if any directory that matches a simple
regexp exists, but using the -d flag. So for example, I would want:

if (-d "/opt/*abc") {
print "Directory exists\n";
};

to print "Directory exists" if there are any directories such as "/opt/
abc", "/opt/123abc", "/opt/asdfghabc", and only fail the condition if
nothing meets it. More than one directory conforming to the regexp
should also successfully print "Directory exists".

Thanks in advance,
-Chris
 
X

xhoster

Hi experts,

A quick (I hope) question...

I want to be able to verify if any directory that matches a simple
regexp exists, but using the -d flag. So for example, I would want:

if (-d "/opt/*abc") {

That isn't a regexp (or at least not a Perl regexp), it is shell expansion
or a glob.
print "Directory exists\n";
};

if (grep -d, glob "/opt/*abc") {


That doesn't stop upon finding the first directory. If that bothers you,
you can use List::Util::first.

Xho
 
C

cprowse

Please put the subject of your post in the Subject of your post.

To do otherwise is very rude.

Apologies - clearly "newbie" applies not just to Perl. Suspect I'm
posting incorrectly to the top or bottom as well.

Xho >> thanks for the clarification and answer, should do exactly what
I want.

Kind Regards,
-Chris
 
R

Randal L. Schwartz

christopher> I want to be able to verify if any directory that matches a simple
christopher> regexp exists, but using the -d flag. So for example, I would want:

christopher> if (-d "/opt/*abc") {
christopher> print "Directory exists\n";
christopher> };

The -d doesn't glob. You need to glob, to glob. :)

my @interesting_dirs = glob "/opt/*abc";
if (@interesting_dirs) {
print "they exist!\n";
}

print "Just another Perl hacker,"; # the original
 
J

Jürgen Exner

I want to be able to verify if any directory that matches a simple
regexp exists, but using the -d flag. So for example, I would want:

Do you mean "but using" or "by using"?
"By using" doesn't work because -d (like all of the file test operators)
takes a file name as argument, not a RE.
if (-d "/opt/*abc") {
print "Directory exists\n";
};

to print "Directory exists" if there are any directories such as
"/opt/ abc", "/opt/123abc", "/opt/asdfghabc", and only fail the
condition if nothing meets it. More than one directory conforming to
the regexp should also successfully print "Directory exists".

Actually, I think this is a non-trivial task.

If you were asking for shell expansion, then the issue would be simple. Just
do a glob() to get all file names and then a grep() with -d to filter for
the directories.

However, glob() doesn't do REs and you specifically asked for REs. I have no
idea how to list any file names based on REs except by walking the directory
tree using e.g. File::Find which of course is slow and cumbersome.

jue
 
J

Jürgen Exner

Randal said:
christopher> I want to be able to verify if any directory that
matches a simple christopher> regexp exists, but using the -d flag.
So for example, I would want:

christopher> if (-d "/opt/*abc") {
christopher> print "Directory exists\n";
christopher> };

The -d doesn't glob. You need to glob, to glob. :)

Well, glob does shell filename globbing only, it doesn't do RE matching.
And the OP was explicitely asking for RE matching which makes the task a lot
more complicated.

jue
 
C

cprowse

Well, glob does shell filename globbing only, it doesn't do RE matching.
And the OP was explicitely asking for RE matching which makes the task a lot
more complicated.

jue

Unfortunately, OP clearly didn't understand his own question.
Apologies, I clearly worded something more confusing than I meant.
Xho's solution seems to do the job, I just want to know if any
directory exists that meets my condition (which I unfortunately called
a regexp, mostly because it has an * in it :S ). Thanks all for your
quick responses.
 
R

Randal L. Schwartz

Jürgen> However, glob() doesn't do REs and you specifically asked for REs. I
Jürgen> have no idea how to list any file names based on REs except by walking
Jürgen> the directory tree using e.g. File::Find which of course is slow and
Jürgen> cumbersome.

There are some evil Unix Intro texts (usually random websites) that call
globbing "regular expressions". Boo. Hiss. But it means that some newbies
that are getting the wrong idea, and then spreading the bad meme.
 
M

Michele Dondi

That isn't a regexp (or at least not a Perl regexp), it is shell expansion
or a glob.

Well, strictly speaking it's a string, period. More loosely, it *can*
be a regex, just not meaning what the OP supposes.


Michele
 
M

Michele Dondi

Well, glob does shell filename globbing only, it doesn't do RE matching.
And the OP was explicitely asking for RE matching which makes the task a lot
more complicated.

A lot? Well nothing that a simple grep() can't handle. Anyway the OP
explicitly asked about RE matching, but *probably* meant globbing.


Michele
 
M

Michele Dondi

if (grep -d, glob "/opt/*abc") {


That doesn't stop upon finding the first directory. If that bothers you,
you can use List::Util::first.

A common error in which I recently got caught too: glob() does -d (in
this case) anyway. So grep -d is redundant.


Michele
 
M

Michele Dondi

A common error in which I recently got caught too: glob() does -d (in
this case) anyway. So grep -d is redundant.

D'Oh! I'm a moron. Ignore this...


Michele
 
J

Jürgen Exner

Michele said:
A lot? Well nothing that a simple grep() can't handle.

True. But how do you get that initial list of file/directory names that you
feed into grep() without generating the full list of all files in all
directories recursively?
I couldn't come up with anything better than the either that or to use
something like File::Find to filter while traversing the tree.

jue
 
M

Michele Dondi

True. But how do you get that initial list of file/directory names that you
feed into grep() without generating the full list of all files in all
directories recursively?

Well, I can't. Of course I can't: grep() takes a list: since we do not
have lazy list evaluation (yet) the list must be generated in advance,
in some way or another. In that case I wouldn't do the check in a grep
but directly in the finding code. OTOH as most of use understood it,
the OP *didn't* want to match *recursively*.
I couldn't come up with anything better than the either that or to use
something like File::Find to filter while traversing the tree.

Indeed.


Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top