home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2551 < prev    next >
Encoding:
Text File  |  1992-11-18  |  12.5 KB  |  518 lines

  1. Newsgroups: alt.sources
  2. Path: sparky!uunet!mcsun!Germany.EU.net!logixwi!jpm
  3. From: jpm@Logix.DE (Jan-Piet Mens)
  4. Subject: lgrep1.0 - search for filenames in ls - output
  5. Organization: Logix GmbH, Wiesbaden, Germany
  6. Date: Wed, 18 Nov 1992 16:03:32 GMT
  7. Message-ID: <1992Nov18.160332.13080@Logix.DE>
  8. Lines: 508
  9.  
  10. Submitted-by: jpm@Logix.DE
  11. Archive-name: LGREP/part01
  12.  
  13. Lgrep reads the input from "ls -R" or "ls -lR" listings and searches for
  14. file names by regular expression, keeping track of the directory name
  15. nestings, in order to build a pathname from the "ls" list relative to
  16. the top of the list. So, 
  17.  
  18.     $ lgrep -P"uucp host!~ftp/" -A"/tmp"    ".*\.c"  archive-list | sh
  19.  
  20. whould transfer all C source files to your /tmp directory. (This could be
  21. rather expensive :-)
  22.  
  23.  
  24. ---- Cut Here and feed the following to sh ----
  25. #!/bin/sh
  26. # This is LGREP, a shell archive (produced by shar 3.49)
  27. # To extract the files from this archive, save it to a file, remove
  28. # everything above the "!/bin/sh" line above, and type "sh file_name".
  29. #
  30. # made 11/18/1992 16:01 UTC by jpm@Logix.DE
  31. # Source directory /home/jpm/src/lgrep
  32. #
  33. # existing files will NOT be overwritten unless -c is specified
  34. #
  35. # This shar contains:
  36. # length  mode       name
  37. # ------ ---------- ------------------------------------------
  38. #    919 -rw-r--r-- README
  39. #   1303 -rw-r--r-- Makefile
  40. #   2440 -rw-r--r-- lgrep.1
  41. #   3330 -rw-r--r-- lgrep.c
  42. #     21 -rw-r--r-- patchlevel.h
  43. #    402 -rw-r--r-- copyright.h
  44. #
  45. # ============= README ==============
  46. if test -f 'README' -a X"$1" != X"-c"; then
  47.     echo 'x - skipping README (File already exists)'
  48. else
  49. echo 'x - extracting README (Text)'
  50. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  51. This is Lgrep-1.0 PL0
  52. =====================
  53. X
  54. Lgrep reads the input from "ls -R" or "ls -lR" listings and searches for
  55. file names by regular expression, keeping track of the directory name
  56. nestings, in order to build a pathname from the "ls" list relative to
  57. the top of the list. So, 
  58. X
  59. X    $ lgrep -P"uucp host!~ftp/" -A"/tmp"    ".*\.c"  archive-list | sh
  60. X
  61. whould transfer all C source files to your /tmp directory. (This could be
  62. rather expensive :-)
  63. X
  64. Installation:
  65. X
  66. X    - Edit the Makefile
  67. X        Set either one of REGCMP or RE_COMP in DEFS 
  68. X        REGCMP is for System V, SCO, ... and
  69. X        RE_COMP is for BSD-type systems
  70. X
  71. X        If you have neither in your libraries, get regexp.[ch]
  72. X        from Emacs, compile them into regexp.o.
  73. X        Define -DRE_COMP and continue;
  74. X
  75. X    - Do a ``make''
  76. X    - If everythings works ok (why shouldn't it ?) do a
  77. X      ``make install''. This will copy the binary to BINDIR
  78. X    - Install the man-page.
  79. X    - Done.
  80. X
  81. X
  82. X    Regards,
  83. X        -JP
  84. SHAR_EOF
  85. chmod 0644 README ||
  86. echo 'restore of README failed'
  87. Wc_c="`wc -c < 'README'`"
  88. test 919 -eq "$Wc_c" ||
  89.     echo 'README: original size 919, current size' "$Wc_c"
  90. fi
  91. # ============= Makefile ==============
  92. if test -f 'Makefile' -a X"$1" != X"-c"; then
  93.     echo 'x - skipping Makefile (File already exists)'
  94. else
  95. echo 'x - extracting Makefile (Text)'
  96. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  97. #
  98. # DEFS
  99. #  -DREGCMP    for System-V regular-expression routines
  100. #  -DRE_COMP    for BSD-ish regular-expression routines
  101. #    If you have neither/nor, get regex.[ch] from Emacs, and define RE_COMP
  102. #
  103. #  -DBSD    If you need <strings.h>
  104. X
  105. # DEFS=-DRE_COMP -DBSD
  106. DEFS=-DREGCMP
  107. X
  108. BINDIR=/usr/local/bin
  109. X
  110. #CC=cc
  111. #CFLAGS=-g $(DEFS) -Wall
  112. CC=gcc
  113. CFLAGS= -O $(DEFS)
  114. X
  115. # On SCO, when compiling with GCC, you'll need ``-lintl''
  116. # On SYSV, you may need -lPW for the reg* routines.
  117. X
  118. LIBS=-lintl
  119. #LIBS=-PW
  120. #LIBS=
  121. X
  122. # If you have regex.o from Emacs or from Henry Spencer, add ``regexp.o''
  123. # to the OBJS= list below.
  124. X
  125. OBJS= lgrep.o # regexp.o
  126. SRCS= lgrep.c
  127. TARGET= lgrep
  128. H=    patchlevel.h copyright.h
  129. X
  130. all: $(TARGET)
  131. X
  132. $(TARGET): $(OBJS)
  133. X    $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
  134. X
  135. $(OBJS): $(SRCS) $(H)
  136. X
  137. clean:
  138. X    rm -f *.o core a.out
  139. clobber: clean
  140. X    rm -f $(TARGET) Part.?? *.a
  141. X
  142. install: $(TARGET)
  143. X    strip $(TARGET)
  144. X    [ -x /usr/bin/mcs ] && /usr/bin/mcs -d $(TARGET)
  145. X    [ -d $(BINDIR) ] || mkdir $(BINDIR)
  146. X    cp $(TARGET) $(BINDIR)/$(TARGET)
  147. X    chmod 111 $(BINDIR)/$(TARGET)
  148. X    chown root $(BINDIR)/$(TARGET)
  149. X
  150. SHARFILES=README Makefile lgrep.1
  151. X
  152. dist: $(SRCS) $(SHARFILES) $(H)
  153. X    shar49 -n LGREP -a -s 'jpm@Logix.DE' -o Part -l 50 -c \
  154. X        $(SHARFILES) $(SRCS) $(H)
  155. X
  156. diffs:
  157. X    (for i in $(H) $(SRCS) $(SHARFILES) ; do rcsdiff -c $$i ; done) || exit 0
  158. SHAR_EOF
  159. chmod 0644 Makefile ||
  160. echo 'restore of Makefile failed'
  161. Wc_c="`wc -c < 'Makefile'`"
  162. test 1303 -eq "$Wc_c" ||
  163.     echo 'Makefile: original size 1303, current size' "$Wc_c"
  164. fi
  165. # ============= lgrep.1 ==============
  166. if test -f 'lgrep.1' -a X"$1" != X"-c"; then
  167.     echo 'x - skipping lgrep.1 (File already exists)'
  168. else
  169. echo 'x - extracting lgrep.1 (Text)'
  170. sed 's/^X//' << 'SHAR_EOF' > 'lgrep.1' &&
  171. .TH LGREP 1 "Logix GmbH"
  172. .SH NAME
  173. lgrep \- search for filenames in ls - output
  174. .SH SYNOPSIS
  175. .B lgrep
  176. [
  177. .B -P
  178. .I prepend
  179. ] [
  180. .B -A
  181. .I append
  182. ] [
  183. .B -v
  184. ]
  185. .B pattern
  186. [
  187. .IR files ...
  188. ]
  189. .SH DESCRIPTION
  190. .I lgrep
  191. is a filter designed to scan the output of a recursive directory listing as
  192. produced by
  193. .IR ls ,
  194. to search for and build pathnames from the input.
  195. .I lgrep
  196. will read the named 
  197. .I files
  198. in order, or standard input if no
  199. .I files
  200. are specified, and will apply the regular expression given in
  201. .B pattern
  202. to each line read from the input, keeping track of directory nesting to
  203. finally produce full pathnames [relative to the top of the listing].
  204. If a file name is specified as
  205. .B - 
  206. the standard input is read.
  207. .SH OPTIONS
  208. .I lgrep
  209. recognizes the following options:
  210. .IP "\fB-v\fR"
  211. show version string and release number.
  212. .IP "\fB-P\fR \fIprepend\fR" 1i
  213. The string in
  214. .I prepend
  215. is prepended to the output produced by
  216. .IR lgrep .
  217. If
  218. .I prepend
  219. contains white space or shell meta characters, it should be quoted.
  220. .IP "\fB-A\fR \fIappend\fR" 1i
  221. The string given in
  222. .I append
  223. is appended to the output produced for each pathname, in a similar way as
  224. with
  225. .I prepend.
  226. .SH EXAMPLE
  227. Supposing the output of 
  228. .I "ls -R"
  229. where
  230. .nf
  231. .in 0.5i
  232. total 378
  233. -rw-r--r--   1 jpm      logix       2591 Apr 11  1992 INSTALL
  234. -r--r--r--   1 jpm      logix       1459 Aug 12  1991 mail.c
  235. -r--r--r--   1 jpm      logix        886 Aug 12  1991 mailserv.c
  236. -rw-r--r--   1 jpm      logix       3270 Apr 11  1992 mail-server.1
  237. -rw-r--r--   1 jpm      logix        914 Aug 15  1991 Makefile
  238. drwxr-xr-x   2 jpm      logix        192 May 27 14:58 RCS
  239. -rw-r--r--   1 jpm      logix       3890 May 27 14:58 send.o
  240. X
  241. ./RCS:
  242. total 62
  243. -r--r--r--   1 jpm      logix       1789 Aug 12  1991 mail.c,v
  244. -r--r--r--   1 jpm      logix        869 Aug 12  1991 mailserv.c,v
  245. -r--r--r--   1 jpm      logix       5027 May 27 14:58 send.c,v
  246. .in
  247. .fi
  248. .PP
  249. then
  250. .PP
  251. .in 0.5i
  252. .nf
  253. X $ ls -lR | lgrep mail
  254. X ./mail.c
  255. X ./mailserv.c
  256. X ./mail-server.1
  257. X ./RCS/mail.c,v
  258. X ./RCS/mailserv.c,v
  259. X $ lgrep -P"cp " -A " /tmp" ".*,v"  archive-list
  260. X cp ./RCS/mail.c,v /tmp
  261. X cp ./RCS/mailserv.c,v /tmp
  262. X cp ./RCS/send.c,v /tmp
  263. .in
  264. .fi
  265. .PP
  266. .SH NOTES
  267. The
  268. .B pattern
  269. given
  270. to
  271. .I lgrep
  272. is a regular expression and not shell-glob specification.
  273. .I lgrep
  274. may be fooled if a file name ends in a colon.
  275. .SH SEE ALSO
  276. .IR ls (1)
  277. and
  278. .IR ed (1)
  279. for a discussion on regular expressions.
  280. .SH AUTHOR
  281. Jan-Piet Mens - <jpm@Logix.DE>
  282. SHAR_EOF
  283. chmod 0644 lgrep.1 ||
  284. echo 'restore of lgrep.1 failed'
  285. Wc_c="`wc -c < 'lgrep.1'`"
  286. test 2440 -eq "$Wc_c" ||
  287.     echo 'lgrep.1: original size 2440, current size' "$Wc_c"
  288. fi
  289. # ============= lgrep.c ==============
  290. if test -f 'lgrep.c' -a X"$1" != X"-c"; then
  291.     echo 'x - skipping lgrep.c (File already exists)'
  292. else
  293. echo 'x - extracting lgrep.c (Text)'
  294. sed 's/^X//' << 'SHAR_EOF' > 'lgrep.c' &&
  295. #include "patchlevel.h"
  296. #include "copyright.h"
  297. X
  298. #include <stdio.h>
  299. #include <sysexits.h>
  300. #include <errno.h>
  301. #ifdef BSD
  302. #    include <strings.h>
  303. #    define  strchr index
  304. #    define    strrchr rindex
  305. #else
  306. #    include <string.h>
  307. #endif
  308. X
  309. #if !defined(REGCMP) && !defined(RE_COMP)
  310. #    error must define one of REGCMP or RE_COMP
  311. #endif
  312. X
  313. #if defined(REGCMP) && defined(RE_COMP)
  314. #    error must define ONLY one of REGCMP or RE_COMP
  315. #endif
  316. X
  317. #ifdef REGCMP
  318. X    extern char *regcmp(), *regex();
  319. #else
  320. X    extern char *re_comp();
  321. X    extern int re_exec();
  322. #endif
  323. X
  324. #ifndef MAXPATHLEN
  325. # define MAXPATHLEN    128
  326. #endif
  327. X
  328. typedef char string[MAXPATHLEN+1];
  329. static char rcs_id[] = "@(#)$Id: lgrep.c,v 1.1 1992/11/18 15:41:18 jpm Exp jpm $";
  330. X
  331. static string Prepend, Append;
  332. static char *progname;
  333. X
  334. int main(argc, argv)
  335. int argc;
  336. char **argv;
  337. {
  338. X    FILE *fp = stdin;
  339. X    int c, i;
  340. X    extern char *optarg;
  341. X    extern int optind;
  342. X    char *re;
  343. X
  344. X    progname = *argv;
  345. X    while ((c = getopt(argc, argv, "P:A:v")) != EOF) {
  346. X        switch (c) {
  347. X            case 'P':
  348. X                strcpy(Prepend, optarg);
  349. X                break;
  350. X            case 'A':
  351. X                strcpy(Append, optarg);
  352. X                break;
  353. X            case 'v':
  354. X                printf("LGREP 1.0PL%d by Jan-Piet Mens - <jpm@Logix.DE>\n",
  355. X                    PATCHLEVEL);
  356. X                return (0);
  357. X            default:
  358. X                return (err(1, (char *)0));
  359. X        }
  360. X    }
  361. X
  362. X    if (optind == argc)
  363. X        return (err(1, (char *)0));
  364. X
  365. X    re = argv[optind];
  366. X    if (optind + 1 == argc)
  367. X        grep(stdin, re);
  368. X    else {
  369. X        for (i = optind + 1; i < argc; i++) {
  370. X            if (!strcmp(argv[i], "-"))
  371. X                fp = stdin;
  372. X            else if ((fp = fopen(argv[i], "r")) == (FILE *)0) {
  373. X                fprintf(stderr, "%s: Can't open %s: %s\n",
  374. X                    progname, argv[i], sys_errlist[errno]);
  375. X                continue;
  376. X            }
  377. X            grep(fp, re);
  378. X            if (fp != stdin)
  379. X                fclose(fp);
  380. X        }
  381. X    }
  382. X    return (EX_OK);
  383. }
  384. X
  385. /*
  386. X * FP is an open file, and RE is a Regular Expression that must be compiled.
  387. X * Run through FP, which contains the output of an ``ls -R'' listing, and
  388. X * find hits, building full pathnames as appropriate.
  389. X */
  390. X
  391. int grep(fp, re)
  392. FILE *fp;
  393. char *re;
  394. {
  395. X    string dirname, buf;
  396. X    char *bp, *compiled, *ptr;
  397. X    int n;
  398. X
  399. #ifdef REGCMP
  400. X    if ((compiled = regcmp(re, (char *)0)) == (char *)0)
  401. X        return (err(0, re));
  402. #else
  403. X    if (re_comp(re) != (char *)0)
  404. X        return (err(0, re));
  405. #endif
  406. X    strcpy(dirname, ".");
  407. X
  408. X    while ((bp = fgets(buf, sizeof(buf), fp)) != (char *)0) {
  409. X
  410. X        buf[n = (strlen(buf) - 1)] = '\0';
  411. X
  412. X        /*
  413. X         * If the last char is now a colon, then we have a directory
  414. X         * name from ``ls''; keep it, and read next line.
  415. X         */
  416. X
  417. X        if (buf[n - 1] == ':') {
  418. X            strcpy(dirname, buf);
  419. X            dirname[n - 1] = '\0';
  420. X            continue;
  421. X        }
  422. X
  423. X        /* Is there a space starting from the right ? If no, then
  424. X         * we have an ``ls -R''. If yes, an ``ls -lR''
  425. X         */
  426. X
  427. X        if ((bp = strrchr(bp, ' ')) != (char *)0)
  428. X            ++bp;
  429. X        else
  430. X            bp = buf;
  431. X
  432. X        /*
  433. X         * BP now points to the file name in the ``ls'' output.
  434. X         * Match it agains the compiled reg-expression, and if
  435. X         * that works, we have a hit!
  436. X         */
  437. X
  438. #ifdef REGCMP
  439. X        if ((ptr = regex(compiled, bp)) != (char *)0)
  440. #else
  441. X        if (re_exec(bp) == 1)
  442. #endif
  443. X        {
  444. X            printf("%s%s/%s%s\n",
  445. X                Prepend, 
  446. X                dirname,
  447. X                bp,
  448. X                Append);
  449. X        }
  450. X    }
  451. X
  452. #ifdef REGCMP
  453. X    (void) free(compiled);
  454. #endif
  455. X    return (0);
  456. }
  457. X
  458. int err(n, s)
  459. int n;
  460. char *s;
  461. {
  462. X    static char *errs[] = {
  463. X        "%s: Illegal Regular Expression in ``%s''\n",
  464. X        "Usage: %s [-P<prepend>] [-A<append>] [-v] pattern [file...]\n"
  465. X    };
  466. X
  467. X    fprintf(stderr, errs[n], progname, s);
  468. X    return (1);
  469. }
  470. SHAR_EOF
  471. chmod 0644 lgrep.c ||
  472. echo 'restore of lgrep.c failed'
  473. Wc_c="`wc -c < 'lgrep.c'`"
  474. test 3330 -eq "$Wc_c" ||
  475.     echo 'lgrep.c: original size 3330, current size' "$Wc_c"
  476. fi
  477. # ============= patchlevel.h ==============
  478. if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
  479.     echo 'x - skipping patchlevel.h (File already exists)'
  480. else
  481. echo 'x - extracting patchlevel.h (Text)'
  482. sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
  483. #define PATCHLEVEL    0
  484. SHAR_EOF
  485. chmod 0644 patchlevel.h ||
  486. echo 'restore of patchlevel.h failed'
  487. Wc_c="`wc -c < 'patchlevel.h'`"
  488. test 21 -eq "$Wc_c" ||
  489.     echo 'patchlevel.h: original size 21, current size' "$Wc_c"
  490. fi
  491. # ============= copyright.h ==============
  492. if test -f 'copyright.h' -a X"$1" != X"-c"; then
  493.     echo 'x - skipping copyright.h (File already exists)'
  494. else
  495. echo 'x - extracting copyright.h (Text)'
  496. sed 's/^X//' << 'SHAR_EOF' > 'copyright.h' &&
  497. /*
  498. X * LGREP, Copyright 1992,   Jan-Piet Mens [Logix GmbH, Wiesbaden, Germany]
  499. X * License to freely use and distribute this software is hereby granted 
  500. X * by the author, subject to the condition that this copyright notice 
  501. X * remains intact.  The author retains the exclusive right to publish 
  502. X * derivative works based on this work, including, but not limited
  503. X * to, revised versions of this work.
  504. X */
  505. SHAR_EOF
  506. chmod 0644 copyright.h ||
  507. echo 'restore of copyright.h failed'
  508. Wc_c="`wc -c < 'copyright.h'`"
  509. test 402 -eq "$Wc_c" ||
  510.     echo 'copyright.h: original size 402, current size' "$Wc_c"
  511. fi
  512. exit 0
  513. -- 
  514.     __  _____   __  __ 
  515.    |  ||  _  \ |  \/  |    Logix GmbH                             jpm@Logix.DE
  516.  __|  ||  ___/ |      |    Moritzstrasse 50, +49-611-309797   jpm@logixwi.UUCP
  517. |_____||__|    |__||__|    D-6200 Wiesbaden  ...!uunet!mcsun!unido!logixwi!jpm
  518.