best [k]sh idiom for "do 1+ files match this wildcard?"?

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by Alex Martel » Mon, 04 Nov 1991 19:32:31



Suppose a sh script (could be ksh, if it helps much) must test whether
there exist one or more files matching a given wildcard spec, which is
in a variable.  What would be the best idiom for that?  I'm looking
both for something that can become "second nature", just as so many
other sh idioms, so that I can type it in without pause when needing
the same thing in the future in some other script (and for this it
would be best to have something in sheer sh, to be as portable as
possible), and for something as fast as possibile, specifically for
a system where pipes and fork are far costlier than ksh builtins (this
is particularly for MKS Tools, a full ksh for Msdos).

So far I have come up with nothing better than, say:
        ls $thevar >/dev/null 2>/usr/tmp/$$
        if test -s /usr/tmp/$$
        then
                echo no files satisfy $thevar
        else
                echo 1+ files satisfy $thevar
        fi
        rm /usr/tmp/$$

All in all, not particularly satisfying.  I've also though about
checking if the output of "echo $thevar" contains stars or question
marks, but this looks even worse (it might be that the "wildcard"
in $thevar doesn't actually *have* any stars or question marks, it
might be that some of the *files* it matches actually have such [well,
not on Dos, but definitely on Unix], and anyway I can't find a simple
and fast way to test that!).  Is it just me, or there *really* is no
way to do that with some clever mix of echo, test and case, which are
builtin and very fast in all target shells?  Or some other builtin
which I have totally overlooked (quite likely for ksh, actually, as
I tend to only use its sh subset in scripts)?  Thanks for any feedback!
--
Alex Martelli - (home snailmail:) v. Barontini 27, 40138 Bologna, ITALIA

voice phone: (work:) +39 (51) 6130360, (home:) +39 (51) 250434;
fax: +39 (51) 6130294 (work only), Fidonet: 332/407.314 (home only).

 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by madhavan.srinivas » Wed, 06 Nov 1991 23:05:04



Quote:(Alex Martelli) writes:
>Suppose a sh script (could be ksh, if it helps much) must test whether
>there exist one or more files matching a given wildcard spec, which is
>in a variable.  What would be the best idiom for that?
> ... [ remarks about speed, portability with example script deleted ]

match=0
for f in $thevar
do
        test -f "$f" && match=1 && break
done

It may not be optimal, but it doesn't spawn any new processes and
doesn't create any files.

- Mad Srinivasan
  AT&T Bell Laboratories


 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by Bob Hallor » Wed, 06 Nov 1991 22:31:12



>Suppose a sh script (could be ksh, if it helps much) must test whether
>there exist one or more files matching a given wildcard spec, which is
>in a variable.  What would be the best idiom for that?  

In the Bolsky/Korn book on ksh, the following pattern matching forms
are given:

        *(pattern [|pattern]...)        Match zero or more of the pattern(s)
        +(pattern [|pattern]...)        Match one or more of the pattern(s)

        !(pattern [|pattern]...)        Match anything BUT the pattern(s)

        so, for example, you could select source files from a
        directory using !(*.o|*.a)

        Sounds as if using +($var) would work for you; an example of
        this, taken from the ksh tutorial book by HP ;

                car+([ted]) matches:

                cart, caret, card, carded, carted    but not

                car, carets

        Hope this helps....

        Bob Halloran
        AT&T Universal Card
        Jacksonville FL


 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by David J. Kleika » Thu, 07 Nov 1991 06:46:46



>Suppose a sh script (could be ksh, if it helps much) must test whether
>there exist one or more files matching a given wildcard spec, which is
>in a variable.  What would be the best idiom for that?
>So far I have come up with nothing better than, say:
>    ls $thevar >/dev/null 2>/usr/tmp/$$
>    if test -s /usr/tmp/$$
>    then
>            echo no files satisfy $thevar
>    else
>            echo 1+ files satisfy $thevar
>    fi
>    rm /usr/tmp/$$

How about:

        #!/bin/ksh
        if test -a $thevar
        then
                echo '1+ files satisfy $thevar'
        else
                echo 'no files satisfy $thevar'
        fi
--
---------------------------------------------------------------------------

The content of this posting is independent of official IBM position.

 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by Knud Christens » Thu, 07 Nov 1991 17:43:38


...

Quote:>So far I have come up with nothing better than, say:
>    ls $thevar >/dev/null 2>/usr/tmp/$$
>    if test -s /usr/tmp/$$
>    then
>            echo no files satisfy $thevar
>    else
>            echo 1+ files satisfy $thevar
>    fi
>    rm /usr/tmp/$$

...

# How about the folowing:

does_expand()
{
  test $# -eq 1 || return 0
  test -f $1 -o -d $1 -o -c $1 -o -b $1

Quote:}

does_expand $thevar

# Hope this helps

>--
>Alex Martelli - (home snailmail:) v. Barontini 27, 40138 Bologna, ITALIA

>voice phone: (work:) +39 (51) 6130360, (home:) +39 (51) 250434;
>fax: +39 (51) 6130294 (work only), Fidonet: 332/407.314 (home only).

Knud Christensen                                     RC International, Denmark

It is better to keep your mouth shut, and look like a fool
 than to open it, and remove all doubt!   - Marx - (Groucho not Karl).

 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by Steven Krauw » Thu, 07 Nov 1991 18:11:31


What you need depends of course on what exactly it is you want.
Are you only looking for ordinary files (incl. size 0), or
do you want directories as well. Or would just any match do?

In the latter case (both ordinary files and dictionaries are ok)
you could do the following (in ksh):

THELIST=`echo $THEVAR`       # gives you either the fully
                             # expanded list, or the regexp
[ -f ${THELIST%% *} -o -d ${THELIST%%  *} ] && echo yes
                             # checks whether the first member
                             # of the list is an actual file or
                             # dir (if not it's got to be the
                             # regexp -- i.e. no match)

If you want only ordinary files you will have to check them all
until you find one:

for I in $THEVAR
do [ -f $I ] && echo yes && break 1
done

And if you want to avoid all the typing you could even make it a
shell function (only in ksh, I suppose), e.g.:

function finda { THELIST=`echo $1`
                 [ -f ${THELIST%% *} -o -d ${THELIST%% *} ] || return 1
               }

--------------
Steven

 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by Billy G. All » Fri, 08 Nov 1991 16:27:09



>Suppose a sh script (could be ksh, if it helps much) must test whether
>there exist one or more files matching a given wildcard spec, which is
>in a variable.  What would be the best idiom for that?  [...]

>So far I have come up with nothing better than, say:
>    ls $thevar >/dev/null 2>/usr/tmp/$$
>    if test -s /usr/tmp/$$
>    then
>            echo no files satisfy $thevar
>    else
>            echo 1+ files satisfy $thevar
>    fi
>    rm /usr/tmp/$$

Try:
        if [ "`echo $thevar*`" != "$thevar*" ]
        then    echo 1+ files satisfy $thevar
        else    echo no files satisfy $thevar

This will work with both the Bourne and Korn shells and uses only built in
commands.
--

|  /|      | 7436 Hartwell      | UUCP......: uunet!edsews!bgalli!bga
|-/-|----- | Dearborn, MI 48126 | Compuserve: 76337,2061
|/  |LLIE  | (313) 582-1540     | Genie.....: BGALLIE

 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by Donn Ca » Sat, 09 Nov 1991 03:16:55


|>Suppose a sh script (could be ksh, if it helps much) must test whether
|>there exist one or more files matching a given wildcard spec, which is
|>in a variable.  What would be the best idiom for that?  [...]
|>

|Try:
|       if [ "`echo $thevar*`" != "$thevar*" ]
|       then    echo 1+ files satisfy $thevar
                                      ^"$thevar"^
|       else    echo no files satisfy $thevar
                                      ^"$thevar"^

|This will work with both the Bourne and Korn shells and uses only built in
|commands.

1. This doesn't work.  Consider:
        $ sh example.sh '*q'
        1+ files satisfy *q
        $ ls *q
        *q: No such file or directory
        $ ls *q*
        q.c
        $
2. It doesn't use only built in commands.  Consider:
        $ ptime sh ssh '*q'
        1+ files satisfy *q
          pid  ppid   utime   stime elapsed name
        14279     0     0.1     0.1     0.5 sh
        14280 14279     0.0     0.0     0.1 echo
        14281 14279     0.0     0.0     0.1 [
        14282 14279     0.0     0.1     0.1 echo
        total           0.1     0.2     0.6

        Granted, "[", or "test", is built into many Bourne shells, but
        not all of them!  For example, the Ultrix 4.2 sh doesn't have a
        built in echo or test, and that's typical of BSD-derived systems.

The following is about the best I can do on this one - but note that it
works ONLY if the "pattern" variable HAS wildcard characters.

        for match in $pattern
        do
                case $match in
                "$pattern")     echo No match.;;
                *)              echo "$pattern ->" $pattern;;
                esac
                break
        done

        $ ptime sh example.sh '*q'
        No match.
          pid  ppid   utime   stime elapsed name
        22068     0     0.0     0.1     0.2 sh
        22069 22068     0.0     0.1     0.1 echo
        total           0.0     0.2     0.3

        Donn Cave, University Computing Services, University of Washington

 
 
 

best [k]sh idiom for "do 1+ files match this wildcard?"?

Post by Mark Brad » Mon, 11 Nov 1991 08:20:42


Quote:>    if [ "`echo $thevar*`" != "$thevar*" ]
>    then    echo 1+ files satisfy $thevar
>    else    echo no files satisfy $thevar
> This will work with both the Bourne and Korn shells ...

No it won't.

        Script started on Sat Nov  9 18:05:47 1991
        $
        $ echo $thevar
        ouch
        $ cat oops
                if [ "`echo $thevar*`" != "$thevar*" ]
                then    echo 1+ files satisfy $thevar
                else    echo no files satisfy $thevar
                fi
        $
        $ date >ouch*
        $ ./oops
        no files satisfy ouch
        $ ls -l ouch*
        -rw-rw-r--  1 msb            29 Nov  9 18:06 ouch*
        $
        script done on Sat Nov  9 18:06:15 1991

One could to something like the above with an additional call to test(1)
if the echo trick seems to show no files, but there is enough variation
between versions of test that I'd rather not use that technique.  I think
the simple call to ls(1) is best.

Even with ls, there are some portability issues.
--

        Western Electric distributes UNIX software without warranty or any
        after-sales support.  There is no publicity and new releases outside
        the Bell System are made only very irregularly.  (More than 3 years
        after the release of the sixth edition of the UNIX system, the
        seventh edition had still not appeared.)          -- John Lions

This article is in the public domain.

 
 
 

1. Is "sh file" equivalent to "cat file | sh"

I'd like to know if "sh file" is exactly the same as "cat file | sh". If there
is any difference, what is it? I'd like to know that in order to write a
utility program to unshar a bunch of files, passing the lines to sh via a
pipe.

--
                       ___   __    ___   __    ___  __
 Marc Baudoin         /  /  /  \  /  /  /  \  /    /  \  /   /   Babassez-vous
 le babasseur fou    /  \  /---/ /  \  /---/ /--  /   / /   /    les uns

2. Star Office /Mail and Errors

3. dowhat=`expr "dowhat.sh" : "\(.*\)\.sh$"`;

4. Flawed rxvt available from major ftp sites

5. more secure?: "#!/bin/sh -" or "#!/bin/sh"

6. Help With Parallel Ping

7. GETSERVBYNAME()????????????????????"""""""""""""

8. Test > &> /dev/null

9. sh says: test "$1" = "" when $1="-b"

10. """"""""My SoundBlast 16 pnp isn't up yet""""""""""""

11. "Standard Journaled File System" vs "Large File Enabled Journaled File System"

12. How to match a "[variable]" or "[var1.var2[var3]]"?

13. "iptables mark with filter fw" vs "u32 match"