Implement grep -f
This commit is contained in:
parent
5ba4f37ec3
commit
a1844fae70
8
grep.1
8
grep.1
|
@ -6,6 +6,8 @@ grep \- search files for a pattern
|
||||||
.RB [ \-EFHchilnqsvx ]
|
.RB [ \-EFHchilnqsvx ]
|
||||||
.RB [ \-e
|
.RB [ \-e
|
||||||
.I pattern ]
|
.I pattern ]
|
||||||
|
.RB [ \-f
|
||||||
|
.I file ]
|
||||||
.I pattern
|
.I pattern
|
||||||
.RI [ file ...]
|
.RI [ file ...]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
@ -40,6 +42,12 @@ Specify a pattern used during the search of the input: an input
|
||||||
line is selected if it matches any of the specified patterns.
|
line is selected if it matches any of the specified patterns.
|
||||||
This option is most useful when multiple -e options are used to
|
This option is most useful when multiple -e options are used to
|
||||||
specify multiple patterns, or when a pattern begins with a dash
|
specify multiple patterns, or when a pattern begins with a dash
|
||||||
|
.TP
|
||||||
|
.B \-f file
|
||||||
|
Read one or more patterns from the file named by the pathname file.
|
||||||
|
Patterns in file shall be terminated by a <newline>. A null pattern can be
|
||||||
|
specified by an empty line in pattern_file. Unless the -E or -F option is
|
||||||
|
also specified, each pattern shall be treated as a BRE.
|
||||||
(`-').
|
(`-').
|
||||||
.TP
|
.TP
|
||||||
.B \-h
|
.B \-h
|
||||||
|
|
40
grep.c
40
grep.c
|
@ -12,11 +12,13 @@
|
||||||
enum { Match = 0, NoMatch = 1, Error = 2 };
|
enum { Match = 0, NoMatch = 1, Error = 2 };
|
||||||
|
|
||||||
static void addpattern(const char *);
|
static void addpattern(const char *);
|
||||||
|
static void addpatternfile(const char *);
|
||||||
static int grep(FILE *, const char *);
|
static int grep(FILE *, const char *);
|
||||||
|
|
||||||
static int Fflag;
|
static int Fflag;
|
||||||
static int Hflag;
|
static int Hflag;
|
||||||
static int eflag;
|
static int eflag;
|
||||||
|
static int fflag;
|
||||||
static int hflag;
|
static int hflag;
|
||||||
static int sflag;
|
static int sflag;
|
||||||
static int vflag;
|
static int vflag;
|
||||||
|
@ -35,7 +37,7 @@ static SLIST_HEAD(phead, pattern) phead;
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
enprintf(Error, "usage: %s [-EFHcilnqsvx] [-e pattern] pattern [files...]\n", argv0);
|
enprintf(Error, "usage: %s [-EFHcilnqsvx] [-e pattern] [-f file] pattern [files...]\n", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -61,6 +63,10 @@ main(int argc, char *argv[])
|
||||||
addpattern(EARGF(usage()));
|
addpattern(EARGF(usage()));
|
||||||
eflag = 1;
|
eflag = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
addpatternfile(EARGF(usage()));
|
||||||
|
fflag = 1;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
hflag = 1;
|
hflag = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -86,11 +92,11 @@ main(int argc, char *argv[])
|
||||||
usage();
|
usage();
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|
||||||
if (argc == 0 && !eflag)
|
if (argc == 0 && !eflag && !fflag)
|
||||||
usage(); /* no pattern */
|
usage(); /* no pattern */
|
||||||
|
|
||||||
/* If -e is not specified treat it as if it were */
|
/* just add literal pattern to list */
|
||||||
if (!eflag) {
|
if (!eflag && !fflag) {
|
||||||
addpattern(argv[0]);
|
addpattern(argv[0]);
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
@ -149,18 +155,30 @@ addpattern(const char *pattern)
|
||||||
tmp = estrdup(pattern);
|
tmp = estrdup(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLIST_FOREACH(pnode, &phead, entry) {
|
|
||||||
if (!strcmp(pnode->pattern, tmp)) {
|
|
||||||
free(tmp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pnode = emalloc(sizeof(*pnode));
|
pnode = emalloc(sizeof(*pnode));
|
||||||
pnode->pattern = tmp;
|
pnode->pattern = tmp;
|
||||||
SLIST_INSERT_HEAD(&phead, pnode, entry);
|
SLIST_INSERT_HEAD(&phead, pnode, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addpatternfile(const char *file)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t len = 0, size = 0;
|
||||||
|
|
||||||
|
fp = fopen(file, "r");
|
||||||
|
if (!fp)
|
||||||
|
enprintf(Error, "fopen %s:", file);
|
||||||
|
while ((len = getline(&buf, &size, fp)) != -1) {
|
||||||
|
if (len && buf[len - 1] == '\n')
|
||||||
|
buf[len - 1] = '\0';
|
||||||
|
addpattern(buf);
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grep(FILE *fp, const char *str)
|
grep(FILE *fp, const char *str)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user