Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!convex!convex.COM From: tchrist@convex.COM (Tom Christiansen) Newsgroups: comp.lang.perl Subject: Re: Globbing Message-ID: <100306@convex.convex.com> Date: 27 Feb 90 23:45:55 GMT References: <15209@bfmny0.UU.NET> Sender: news@convex.com Reply-To: tchrist@convex.COM (Tom Christiansen) Organization: CONVEX Software Development, Richardson, TX Lines: 99 Tom Neff writes: >I should get off my duff and code this as a Perl function > > @foo = &REglob("/usr/tmp/id[0-9]{2,5}.$XVAL"); > >first for demonstration purposes -- unless Randal wants to take up >the challenge. :-) Well, this one will work for the "simple" non-recursive case you posted. It's based on the &glob function I posted a few days ago. I don't want to code of the recursive one until patch9. Note that if Larry changes perl's globbing to be internal with full rexprs, there will have to be some kind of support for the old method of "?" and "*" for "." and ".*". I somewhat like the idea of being REglob and being SHglob, although if we could find some unused punctuation, you could add a new special variable, like ${ that turned on REglob if set. Other possibilities exist. I notice that with csh you can do tilda globbing: ($file) = <~tchrist/.cshrc>; If globbing is internalized, support for tilda would be nice to keep. Here's my glob tester for Tom Neff's example. I admit to embarrassment over using rindex and substr over regexps, but it coded up easier that way. Also, I'd love to use /o on a couple things here, but that would mean only being able to call the function once. Any way to invalidate the /o thing? I would like to do a grep(/$expr/o, @args) where the $expr is only compiled once per new grep but not at every internal iteration of grep, and I don't think it's currently feasible. That way you could do: for $expr (@list) { for $item (@other_list) { &foo if $item =~ /$expr/o; } } and have the $expr compiled only once per iteration of the outer loop. You might also want not to always autmatically exclude files starting with dot, or not to always sort the entries. There's a lot of room for discussion here. --tom #!/usr/bin/perl $debug = 1; for ( print "glob> "; ; print "glob> ") { chop; @list = &REglob($_); for ($i = 0; $i <= $#list; $i++) { print "$i $list[$i]\n"; } } sub REglob { local($path) = @_; local(@retlist) = (); local($root,$expr,$pos); local($fakedot) = 0; local(*METADIR); if (($pos = rindex($path, '/')) >= $[) { $root = substr($path, $[, $pos); $expr = substr($path, $pos+1, 999); } else { $fakedot = 1; $root = '.'; $expr = $path; } print "REglob: root is $root, expr is $expr\n" if $debug; unless (opendir(METADIR, $root)) { warn "glob: can't opendir \"$root\": $!\n"; } else { @retlist = sort grep(/^$expr$/, grep(!/^\./, readdir(METADIR))); closedir METADIR; } unless ($fakedot) { for (@retlist) { s!^!$root/!; } } return @retlist; } -- Tom Christiansen {uunet,uiucdcs,sun}!convex!tchrist Convex Computer Corporation tchrist@convex.COM "EMACS belongs in : Editor too big!"