[comp.lang.perl] Help! Need semi-basename

abc@Matrix.COM (Alan Clegg) (07/03/90)

I need to strip a file name to a certain component in Perl, and am not sure
how to go about doing it.

the file names are defined in a configuration file as follows:
	/file/name/and/sub/dirs/*/*

which I then expand into an array of 'real' names:
	@ary=<${name}>;

what I want to do at this point is make links to the files based on
the expansion of the '*/*' in the config file.

For example, if a file expands into /file/name/and/sub/dirs/one/two, I want
to link it to /otherfile/othername/and/othersub/otherdirs/one/two

I can't figure out how to strip off everything 'up-to' the wildcard.  Anybody
know how to do what I am asking?  Anybody UNDERSTAND what I am asking??

-abc
--
      __ _
     / // \  Matrix             Alan B. Clegg
    / //  /_  Corporation       UNIX Systems Administrator
   / //  // \                   (919) 231-8000
  / //  //   \          UUCP:   ...!mcnc!matrx!clegg	(NOTE: no i in matrx)
 / //  //     \     Internet:   clegg@matrix.com	(Note: matrix has an i)
/_//__//_______\

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (07/04/90)

In article <1990Jul2.205216.3857@Matrix.COM> abc@matrx.matrix.com (Alan Clegg) writes:
: I need to strip a file name to a certain component in Perl, and am not sure
: how to go about doing it.
: 
: the file names are defined in a configuration file as follows:
: 	/file/name/and/sub/dirs/*/*
: 
: which I then expand into an array of 'real' names:
: 	@ary=<${name}>;
: 
: what I want to do at this point is make links to the files based on
: the expansion of the '*/*' in the config file.
: 
: For example, if a file expands into /file/name/and/sub/dirs/one/two, I want
: to link it to /otherfile/othername/and/othersub/otherdirs/one/two
: 
: I can't figure out how to strip off everything 'up-to' the wildcard.  Anybody
: know how to do what I am asking?  Anybody UNDERSTAND what I am asking??

Well, a filename is just a string, albeit a rather structured one.
Try something like

	($base,$wild) = $name =~ m#^([^*?[]*)/([^/]*[*?[].*)#;

The first [] matches the longest sequence of non-metacharacters it can,
subject to the constraint that the next character has to be a slash.
After that, it has to match some sequence of non-slash characters followed
by at least one metacharacter followed by the rest of the string.

If you're uncomfy with that, say

	@wild = split(m#/#, $name);
	@base = ();
	while (@wild) {
	    last if $wild[0] =~ /[*?[]/;
	    push(@base, shift(@wild));
	}
	$base = join('/', @base);
	$wild = join('/', @wild);

The first way's probably a bit faster, though.

Larry