On Fri, Jul 16, 2004 at 05:28:57PM +0300, Peter Pentchev wrote:
> On Fri, Jul 16, 2004 at 11:58:07AM +0400, Denis Antrushin wrote:
> > Alfred Perlstein wrote:
> > >I'm up too late, this doesn't work because find returns
> > >success whenever it successfully runs thought everything.
> > >
> > >Perhaps the primary change to just "-exit" which would
> > >make find exit successfully, and if the primary is never
> > >encountered (ie. our find logic never hits it) find would
> > >exit with a non-zero exit status?
> > >
> > >Ideas?  Better ideas?
> > >
> > >The reason I want this is to avoid extracting a tarball
> > >over a directory that has files in it that are newer than
> > >the tarball.
> > >
> > >Neither tar nor find seem to make this easy...
> > What about this:
> > 
> > test -n "`find . -type f -newer ../src.tar.gz`" && echo hi
> 
> I believe Alfred's problem with this is that it will still traverse the
> whole hierarchy even after a match is found.  In some cases, the
> hierarchy may be huge, and if the match is within the first 100-200
> files, well... :)
> 
> I wonder if it wouldn't be a bit better to add to find(1) something like
> -maxmatches N, similar to Alfred's idea, but not limited to a single
> match?

Well, I've just gone ahead and implemented it: say hello to the new
-maxmatch N and -minmatch N primaries:

  -maxmatch n
     Always true; exits after printing out n matching filenames.  If
     any -maxmatch primary is specified, it applies to the entire
     expression even if it would not normally be evaluated.  -maxmatch
     0 makes find exit immediately without performing any filesystem
     traversal.

  -minmatch n
     Always true; exits with a non-zero exit code if less than n
     matching filenames were printed out at the end of the search.  If
     any -minmatch primary is specified, it applies to the entire
     expression even if it would not normally be evaluated.

Thus, -maxmatch 1 would help in Alfred's case.  Patch attached.

G'luck,
Peter

-- 
Peter Pentchev  [EMAIL PROTECTED]    [EMAIL PROTECTED]    [EMAIL PROTECTED]
PGP key:        http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint FDBA FD79 C26F 3C51 C95E  DF9E ED18 B68D 1619 4553
I had to translate this sentence into English because I could not read the original 
Sanskrit.
Index: src/usr.bin/find/extern.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/extern.h,v
retrieving revision 1.21
diff -u -r1.21 extern.h
--- src/usr.bin/find/extern.h   28 May 2004 17:17:15 -0000      1.21
+++ src/usr.bin/find/extern.h   16 Jul 2004 15:09:49 -0000
@@ -68,6 +68,7 @@
 creat_f        c_links;
 creat_f        c_ls;
 creat_f        c_mXXdepth;
+creat_f        c_mXXmatch;
 creat_f        c_name;
 creat_f        c_newer;
 creat_f        c_nogroup;
@@ -116,6 +117,7 @@
 
 extern int ftsoptions, isdeprecated, isdepth, isoutput, issort, isxargs;
 extern int mindepth, maxdepth;
+extern int minmatch, maxmatch, match;
 extern int regexp_flags;
 extern time_t now;
 extern int dotfd;
Index: src/usr.bin/find/find.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/find.1,v
retrieving revision 1.66
diff -u -r1.66 find.1
--- src/usr.bin/find/find.1     7 Jul 2004 19:57:15 -0000       1.66
+++ src/usr.bin/find/find.1     16 Jul 2004 15:19:36 -0000
@@ -442,6 +442,18 @@
 not normally be evaluated.
 .Ic -maxdepth Li 0
 limits the whole search to the command line arguments.
+.It Ic -maxmatch Ar n
+Always true; exits after printing out
+.Ar n
+matching filenames.
+If any
+.Ic -maxmatch
+primary is specified, it applies to the entire expression even if it would
+not normally be evaluated.
+.Ic Ic -maxmatch Li 0
+makes
+.Nm
+exit immediately without performing any filesystem traversal.
 .It Ic -mindepth Ar n
 Always true; do not apply any tests or actions at levels less than
 .Ar n .
@@ -451,6 +463,14 @@
 not normally be evaluated.
 .Ic -mindepth Li 1
 processes all but the command line arguments.
+.It Ic -minmatch Ar n
+Always true; exits with a non-zero exit code if less than
+.Ar n
+matching filenames were printed out at the end of the search.
+If any
+.Ic -minmatch
+primary is specified, it applies to the entire expression even if it would
+not normally be evaluated.
 .It Ic -mmin Ar n
 True if the difference between the file last modification time and the time
 .Nm
Index: src/usr.bin/find/find.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/find.c,v
retrieving revision 1.17
diff -u -r1.17 find.c
--- src/usr.bin/find/find.c     28 May 2004 17:17:15 -0000      1.17
+++ src/usr.bin/find/find.c     16 Jul 2004 15:16:10 -0000
@@ -181,6 +181,10 @@
        PLAN *p;
        int rval;
 
+       if (maxmatch == 0)
+               return (0);
+
+       match = 0;
        tree = fts_open(paths, ftsoptions, (issort ? find_compare : NULL));
        if (tree == NULL)
                err(1, "ftsopen");
@@ -237,5 +241,11 @@
                        (p->execute)(p, NULL);
        if (errno)
                err(1, "fts_read");
+
+       if (match < minmatch) {
+               warnx("Only %d of requested %d matches found",
+                   match, minmatch);
+               rval = 1;
+       }
        return (rval);
 }
Index: src/usr.bin/find/function.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/function.c,v
retrieving revision 1.50
diff -u -r1.50 function.c
--- src/usr.bin/find/function.c 28 May 2004 17:17:15 -0000      1.50
+++ src/usr.bin/find/function.c 16 Jul 2004 15:14:20 -0000
@@ -355,6 +355,36 @@
 }
 
 /*
+ * -maxmatch/-minmatch n functions --
+ *
+ *        If -maxmatch is specified, the search will stop after printing
+ *        out as many matching file names.  If -minmatch is specified and
+ *        at the end of the search there were less matching files found,
+ *        find will print out a warning and exit with a non-zero exit code.
+ *
+ *        Note that -maxmatch and -minmatch are handled specially in
+ *        find_execute() so their f_* functions are set to f_always_true().
+ */
+PLAN *
+c_mXXmatch(OPTION *option, char ***argvp)
+{
+       char *dstr;
+       PLAN *new;
+
+       dstr = nextarg(option, argvp);
+       if (dstr[0] == '-')
+               /* all other errors handled by find_parsenum() */
+               errx(1, "%s: %s: value must be positive", option->name, dstr);
+
+       new = palloc(option);
+       if (option->flags & F_MAXDEPTH)
+               maxmatch = find_parsenum(new, option->name, dstr, NULL);
+       else
+               minmatch = find_parsenum(new, option->name, dstr, NULL);
+       return new;
+}
+
+/*
  * -acl function --
  *
  *     Show files with EXTENDED ACL attributes.
@@ -1216,6 +1246,9 @@
 f_print(PLAN *plan __unused, FTSENT *entry)
 {
        (void)puts(entry->fts_path);
+       match++;
+       if (match == maxmatch)
+               exit(0);
        return 1;
 }
 
@@ -1238,6 +1271,9 @@
 {
        fputs(entry->fts_path, stdout);
        fputc('\0', stdout);
+       match++;
+       if (match == maxmatch)
+               exit(0);
        return 1;
 }
 
Index: src/usr.bin/find/main.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/main.c,v
retrieving revision 1.15
diff -u -r1.15 main.c
--- src/usr.bin/find/main.c     14 Jun 2003 13:00:21 -0000      1.15
+++ src/usr.bin/find/main.c     16 Jul 2004 15:07:00 -0000
@@ -74,6 +74,8 @@
 int issort;                    /* do hierarchies in lexicographical order */
 int isxargs;                   /* don't permit xargs delimiting chars */
 int mindepth = -1, maxdepth = -1; /* minimum and maximum depth */
+int minmatch = -1, maxmatch = -1; /* minimum and maximum number of matches */
+int match;                     /* current number of matches */
 int regexp_flags = REG_BASIC;  /* use the "basic" regexp by default*/
 
 static void usage(void);
Index: src/usr.bin/find/option.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/option.c,v
retrieving revision 1.22
diff -u -r1.22 option.c
--- src/usr.bin/find/option.c   28 May 2004 17:17:15 -0000      1.22
+++ src/usr.bin/find/option.c   16 Jul 2004 15:01:11 -0000
@@ -94,7 +94,9 @@
        { "-links",     c_links,        f_links,        0 },
        { "-ls",        c_ls,           f_ls,           0 },
        { "-maxdepth",  c_mXXdepth,     f_always_true,  F_MAXDEPTH },
+       { "-maxmatch",  c_mXXmatch,     f_always_true,  F_MAXDEPTH },
        { "-mindepth",  c_mXXdepth,     f_always_true,  0 },
+       { "-minmatch",  c_mXXmatch,     f_always_true,  0 },
        { "-mmin",      c_Xmin,         f_Xmin,         0 },
        { "-mnewer",    c_newer,        f_newer,        0 },
        { "-mtime",     c_Xtime,        f_Xtime,        0 },

Attachment: pgpYsWWgleAQp.pgp
Description: PGP signature

Reply via email to