Idiom for $(ls -d $pattern 2>/dev/null)

Leo de Wit leo at philmds.UUCP
Thu Mar 23 05:20:05 AEST 1989


In article <2189 at solo11.cs.vu.nl> maart at cs.vu.nl (Maarten Litmaath) writes:
|das at lanai.cs.ucla.edu writes:
|
|\Do you have a favorite idiom for (ksh syntax):
|\	for f in *
|\(Which is not what you really want, since if the directory is empty, f takes on
|\the value "*").
|
|set - `
|	for i in .* *
|	do
|		echo "$i"
|	done | sed -e '/^\.$/d' -e '/^\.\.$/d'
|`
|[ -f "$1" ] && {
|	for i
|	do
|		echo "$i"
|	done
|}

Yes, but the guy also said:
|that does not involve invocation of a separate process and is not aesthetically
|unpleasant?  The intent is that if any filenames match the pattern, then use
|them; otherwise, use the null string.

Your solution needs several addition process invocations (especially
when 'echo' is not a shell builtin). It selects 'all files in current
directory' instead of those matching $pattern (though that can easily
be fixed).

Alternative that uses only builtins:

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.
         *)     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

and now you can use $* as the list of files; it is empty if there was
no match. You might want to convert this into a ksh function (I'm not
familiar with this shell).

    Leo.



More information about the Comp.unix.questions mailing list