Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sdd.hp.com!spool.mu.edu!uunet!rbj From: rbj@uunet.UU.NET (Root Boy Jim) Newsgroups: comp.lang.perl Subject: Re: path truncation quest Keywords: path,truncation Message-ID: <126224@uunet.UU.NET> Date: 21 Mar 91 21:34:28 GMT Article-I.D.: uunet.126224 References: <1991Mar21.010547.13331@convex.com> <1991Mar21.064642.29427@eng.umd.edu> Organization: UUNET Communications Services, Falls Church, VA Lines: 61 In article <1991Mar21.064642.29427@eng.umd.edu> ziegast@eng.umd.edu (Eric W. Ziegast) writes: >In article <1991Mar21.010547.13331@convex.com> you write: >>given the argument "/directory/sub/100.host.0" >>[how do you remove the last component], leaving "/directory/sub" ? > >At first, I thought about using an array: > > @tmp = split(/\//,$path); > $dir = join("/",pop(@tmp)); Or, you could reverse it, s;[^/]*;;, and reverse again. >But in Perl, there's always a better way of doing things: At least one. > $path =~ s/((\/[^\s\/]+)+)\/([^\s\/]+)/$1/; > >A simplified version would be: > > /((\/F)+)+)\/(F)/ Too complex. First, pick another delimiter, and get rid of the \/'s. Second, there is no sense saving the last pattern. Third, and most importantly, you are going overboard. Restated, the goal is "keep everything up to but not including the last slash". Translated, this becomes: $path =~ s"^(.*)/.*$"$1" Alternately, the goal can be restated "throw away everything including and after the last slash". Translated, this becomes: $path =~ s"/[^/]*$"" > F matches a one word file/directory name. > In my example I use [^\s\/]+ which simply matches > any word without whitespace or "/" in it. > You may want to use something more strict instead. Actually, less strict. Slashes are all that count. OK, nulls too, but I'm ignoring them for now. s/\0.*// if you really care. > $1 will match the directory path. (man dirname) > $2 is used only for /F grouping > $3 will match the base name. (man basename) Aha! It seems that you have adapted a general routine. >This is, of course, only if it's a full path name. Anything else >won't match (and won't be changed). Which may or may not matter to the caller. But onward. I can think of a few other ways. 1) use rindex and substr 2) 1 while (chop($path) ne '/') 3) first, we generate pi/4 :-) -- [rbj@uunet 1] stty sane unknown mode: sane