in reply to Having trouble returning the correct values from my sub
Point 1: Do not use glob! You could be and probably are heading down the path to what I call "glob hell". I spent a lot of hours there until I figured out how to avoid this place! As it turns out glob() is not portable even amongst Unix platforms. And when you throw Microsoft in there it gets even worse! I know of at least 4 kinds of glob() and they aren't compatible! Bummer! But there is a way...sub get_directory{ my @dirs = glob("C:\\Documents and Settings\\mydirectory\\Desktop\ +\KOMP\\*"); foreach my $maid_dir(@dirs){ if (-d $maid_dir){ # directory check if ($maid_dir=~m%\d+\s[A-Z]%){ # match the dir name return $maid_dir; } } } }
Point 2: Perl is designed with Unix style path names, so there is no need to have C:\\dir\\dir2, just use C:/dir/dir2. Perl will translate the / to \ for Windows.
Point 3: Since we aren't going to use glob() there is no need for *.
First some code...
The way to avoid glob() is to open a directory and use grep{} to get what you want. An important part here is that when you use readdir, you only get the name in that directory, NOT the full file path. So you have to add that back in if you do a test on that name. Remember that a directory is just a name, like a file name AND . (the current dir) and .. (the parent directory) will be included in that list! Unix does some special things with files that start with ".", but that doesn't matter here.#!/usr/bin/perl -w use strict; my $dir = "C:/Documents and Settings/mydirectory/Desktop/KOMP"; opendir (D, $dir) || die "can't open directory $dir"; my @sub_dirs = grep {!/^\./ && -d "$dir/$_"}readdir D; print join("\n",@sub_dirs),"\n";
The above code opens a directory. Then it gets a list of sub_directories. The grep{} says: forget any name that starts with a "dot", then test the full path name to see if it is a directory, if so then move it to the output list.
It is unclear to me what $maid_dir=~m%\d+\sA-Z% is trying to accomplish. That says: directory name has one or more digits somewhere (might not be at the beginning of the name), followed by exactly one white space character, followed by one capital letter and what happens after that doesn't matter. Maybe that's not what you want? Maybe you meant that name must start with a digit? then use /^/ anchor.
The above could be shorter, but you can feed a grep{} into another grep{} this is the same as a logical AND.# #example: #@dir_names = get_sub_dirs($path); get_sub_dirs { my $dir = shift; opendir (D, $dir) || die "can't open directory $dir"; my @sub_dirs = grep{/^\d+\s[A-Z]/} grep {!/^\./ && -d "$dir/$_"}readdir D; return (@sub_dirs); }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Having trouble returning the correct values from my sub
by lomSpace (Scribe) on Mar 03, 2009 at 19:09 UTC |