[comp.unix.questions] Re^2: Idiom for $

maart@cs.vu.nl (Maarten Litmaath) (03/23/89)

leo@philmds.UUCP (Leo de Wit) writes:
\set - $pattern             # expand into $*

\case $# in
\1)  p1="$1"                # one arg only; could be mismatch.
\    set - $pattern?*       # retry with other pattern (one char extra).
\    n2=$#                  # save number of matches.
\    set - $pattern*        # retry with yet another pattern.
\    case $# in             # 1 <= $n2 <= $# holds now.
\    1)   case $1 in
\         "$p1") : ;;       # valid match on $p1.
                              ^^^^^^^^^^^
			      not always (see below)

\         *)     shift;;    # no match; empty $*.
\         esac;;
\    $n2) set ""; shift;;   # matches for $pattern* == # matches for $pattern?*,
\                           #     so no match on $p1; empty $*.
\    *)   set "$p1";;       # $# > n2 so there was a valid match on $p1.
\    esac;;
\esac

That can be done far more easier!

	set - $pattern

	case $# in
	1)
		case $pattern in
		$1)
			shift	# neglect pathological file names like *[QZ]
		esac
	esac

Notice the trick: normally $pattern won't match $1 -

	"bin" matches "b??", but "b??" doesn't match "bin"

Shortcomings: Leo's script will incorrectly let "*[QZ]" match itself,
my script won't let * match itself.
I guess one needs at least 1 invocation of `test'.
The `shift' statement should be replaced with:

			case $1 in
			*[[?*]*)
				[ -f $1 -o -d $1 ] || shift
				;;
			*)
				shift
			esac

If `patterns' without special characters are allowed, simply:

			[ -f $1 -o -d $1 ] || shift
-- 
 Modeless editors and strong typing:   |Maarten Litmaath @ VU Amsterdam:
   both for people with weak memories. |maart@cs.vu.nl, mcvax!botter!maart

leo@philmds.UUCP (Leo de Wit) (03/25/89)

In article <2206@solo2.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
|leo@philmds.UUCP (Leo de Wit) writes:
   [my shell script]
|That can be done far more easier!
|
|	set - $pattern
|
|	case $# in
|	1)
|		case $pattern in
|		$1)
|			shift	# neglect pathological file names like *[QZ]
|		esac
|	esac
|
|Notice the trick: normally $pattern won't match $1 -
|
|	"bin" matches "b??", but "b??" doesn't match "bin"

But this fails to recognize patterns without meta-characters. For
instance:  if you have a file named foo, and pattern=foo. My method
_does_ recognize that, and correctly decides whether the file exists.

|Shortcomings: Leo's script will incorrectly let "*[QZ]" match itself,

That is correct; I overlooked the fact that one can construct a filename
that will not match itself as a wildcard expression. It has to be
pretty weird, though (all wildcard expressions consisting of normal
characters, * and ? always match themselves as filenames, if I'm not
mistaken, so it has to contain a [...] range expression. Even this can
probably be handled if one tries hard enough).

|my script won't let * match itself.
|I guess one needs at least 1 invocation of `test'.

If test is not a builtin, I'd probably go for the ls -d $pattern
2>/dev/null method; it is shorter, clearer and probably just as fast.

	 Leo.