From: Akim Demaille <[EMAIL PROTECTED]>
  Date: 06 Jul 2000 17:03:52 +0200

  echo $dir | sed '/^\/*$/!s,//*$,,;s,[^/]*$,,;s,//*$,/,;/^\/$/!s,/$,,'

It's not portable to use "echo".  On some hosts, "echo" mishandles
backslashes and/or names beginning with "-".

It's more portable to use "expr", like this:

expr \
  "X$dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
  "X$dir" : 'X\(//\)[^/]' \| \
  "X$dir" : 'X\(//\)$' \| \
  "X$dir" : 'X\(/\)' \| \
  . : '\(.\)'

This implementation is portable to all POSIX.1 or traditional hosts,
including the treatment of leading //.

Here is a shell script (derived from yours) that illustrates how this
implementation compares to alexandre's and GNU dirname's output.  The
expr implementation agrees with GNU dirname except in some cases with
leading //, where it generates output that is more portable than GNU
dirname's output.

#! /bin/sh

format="%12s %12s %12s %12s\n"

# alexandre, GNU dirname, eggert
printf "$format" "dir" "al" "dn" "eg"

for dir in //1 /1 ./1 ../../2 \
           '' 1 ///1 ///1/2 ///1//2 \
           //1/ /1/ ./1/ ../../2 \
           //1/3 /1/3 ./1/3 ../../2/3 \
           //1/3/// /1/3/// ./1/3/// ../../2/3/// \
           //1//3/ /1//3/ ./1//3/ ../../2//3/
do
  al=`echo "$dir" | sed '/^\/*$/!s,//*$,,;s,[^/]*$,,;s,//*$,/,;/^\/$/!s,/$,,'`
  dn=`command dirname "$dir"`
  eg=`expr \
    "X$dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
    "X$dir" : 'X\(//\)[^/]' \| \
    "X$dir" : 'X\(//\)$' \| \
    "X$dir" : 'X\(/\)' \| \
    . : '\(.\)'
  `
  printf "$format" "$dir" "$al" "$dn" "$eg"
  # echo "$dir  $al     $dn"
done


$ sh dirname.sh
         dir           al           dn           eg
         //1            /            /           //
          /1            /            /            /
         ./1            .            .            .
     ../../2        ../..        ../..        ../..
                                     .            .
           1                         .            .
        ///1            /            /            /
      ///1/2         ///1         ///1         ///1
     ///1//2         ///1         ///1         ///1
        //1/            /            /           //
         /1/            /            /            /
        ./1/            .            .            .
     ../../2        ../..        ../..        ../..
       //1/3          //1          //1          //1
        /1/3           /1           /1           /1
       ./1/3          ./1          ./1          ./1
   ../../2/3      ../../2      ../../2      ../../2
    //1/3///          //1          //1          //1
     /1/3///           /1           /1           /1
    ./1/3///          ./1          ./1          ./1
../../2/3///      ../../2      ../../2      ../../2
     //1//3/          //1          //1          //1
      /1//3/           /1           /1           /1
     ./1//3/          ./1          ./1          ./1
 ../../2//3/      ../../2      ../../2      ../../2

Reply via email to