[alt.sources] cgname - collect file names from {e,f,}grep output

wht@tridom.uucp (Warren Tucker) (06/24/89)

This quickie collects the filenames produced by grep output
while passing the output oin to stdout.  I wrote it to help
me build a list of filenames to edit containing a certain string:

usage: {e,f,}grep <pattern> <flist> | cgname <cfile> [| ...]\n");
collects list of files reported by grep into <cfile>\n");
cgname reads grep output, passing it on to cgname's stdout\n");
and produces a sorted list of filenames into <cfile>\n");

i.e.:

    fgrep BLAH *.[ch] | cgname /tmp/123 
    vi `cat /tmp/123`

{awk,sed,perl}-fanatic flames > /dev/null

/*+-------------------------------------------------------------------------
    cgname.c - pass thru {e,f,}grep output, collecting filenames
    ...!gatech!emory!tridom!wht
--------------------------------------------------------------------------*/
/*+:EDITS:*/
/*:06-23-1989-17:34-wht-creation */

#include <stdio.h>

#define ff fprintf
#define se stderr

FILE *fptmp;

#if defined(M_XENIX) | defined(USG) | defined(SYSV) /* etc */
#define Strchr strchr
#else
#define Strchr index    /* BSD */
#endif

char *Strchr();

/*+-------------------------------------------------------------------------
    collect_name(grepstr)
--------------------------------------------------------------------------*/
int
collect_name(grepstr)
register char *grepstr;
{
register char *cptr;

    if(!(cptr = Strchr(grepstr,':')))
        return(1);
    fwrite(grepstr,1,(int)(cptr - grepstr),fptmp);
    fputc('\n',fptmp);
    return(0);

}   /* end of collect_name */

/*+-------------------------------------------------------------------------
    main(argc,argv,envp)
--------------------------------------------------------------------------*/
main(argc,argv,envp)
int argc;
char **argv;
char **envp;
{
register found_output = 0;
char tmpname[32];
char s256[256];

    if((argc == 1) || (*argv[1] == '-'))
    {
        ff(se,"usage: {e,f,}grep <pattern> <flist> | cgname <cfile> [| ...]\n");
        ff(se,"collects list of files reported by grep into <cfile>\n");
        ff(se,"cgname reads grep output, passing it on to cgname's stdout\n");
        ff(se,"and produces a sorted list of filenames into <cfile>\n");
        exit(1);
    }

    sprintf(tmpname,"/tmp/c%05d.tmp",getpid());
    if((fptmp = fopen(tmpname,"w")) == NULL)
    {
        perror("cgname: cannot open temp file");
        exit(1);
    }

    while(fgets(s256,sizeof(s256),stdin))
    {
        if(collect_name(s256))
        {
            fputs(
            "cgname: missing filename from grep output (only 1 file?)\n",se);
            found_output = 0;
            break;
        }
        found_output = 1;
        fputs(s256,stdout);
    }
    fclose(fptmp);

    if(found_output)
    {
        sprintf(s256,"sort -u %s > %s",tmpname,argv[1]);
        system(s256);
    }

    unlink(tmpfile);
    exit(!found_output);
}   /* end of main */

/* end of cgname.c */
-- 
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation       ...!gatech!emory!tridom!wht 
Sforzando (It., sfohr-tsahn'-doh).  A direction to perform the tone
or chord with special stress, or marked and sudden emphasis.

dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (06/24/89)

In article <130@tridom.uucp> wht@tridom.uucp (Warren Tucker) writes:
>This quickie collects the filenames produced by grep output
>while passing the output oin to stdout.

Was this supposed to compile?  There is a statement

	  unlink(tmpfile);

but there is no variable called tmpfile defined anywhere.
-- 
Rahul Dhesi <dhesi@bsu-cs.bsu.edu>
UUCP:    ...!{iuvax,pur-ee}!bsu-cs!dhesi

rsalz@bbn.com (Rich Salz) (06/24/89)

>    fgrep BLAH *.[ch] | cgname /tmp/123 
>    vi `cat /tmp/123`

At the expense of running the command twice, this can be done with
the standard tools:
	fgrep BLAH *.[ch]
	vi `fgrep -l BLAH *.[ch]`
Usually most folks will just skip the first invocation.

I use the following CSH aliases often:
	alias S 'set x = ( \!* )'
	alias F 'fgrep -l \!$ $x'
	alias V 'vi +/\!$ `fgrep -l \!$ $x`'

For example:
	prompt% cd ~/typedef
	prompt% S *.[cylh]
	prompt% V TypeDefinition
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.

jordan@Morgan.COM (Jordan Hayes) (06/25/89)

Warren Tucker <wht@tridom.uucp> writes:

	>>>    fgrep BLAH *.[ch] | cgname /tmp/123 
	>>>    vi `cat /tmp/123`

	>>>    {awk,sed,perl}-fanatic flames > /dev/null

Sure, awk/sed/perl could do the same, but what about this:

	% vi `fgrep -l BLAH *.[ch]`
	% vi `fgrep -l BLAH *.[ch] | tee /tmp/123`	# if you want the list

or

	% alias vl vi '`fgrep -l \!*`'			# c-shell
	% vl BLAH *.[ch]

"When I was a boy, we didn't even *have* manuals ..."

/jordan

jeff@quark.WV.TEK.COM (Jeff Beadles) (06/25/89)

In article <130@tridom.uucp> wht@tridom.uucp (Warren Tucker) writes:
|This quickie collects the filenames produced by grep output
|while passing the output oin to stdout.  I wrote it to help
|me build a list of filenames to edit containing a certain string:
|
|usage: {e,f,}grep <pattern> <flist> | cgname <cfile> [| ...]\n");
|collects list of files reported by grep into <cfile>\n");
|cgname reads grep output, passing it on to cgname's stdout\n");
|and produces a sorted list of filenames into <cfile>\n");
|
|i.e.:
|
|    fgrep BLAH *.[ch] | cgname /tmp/123 
|    vi `cat /tmp/123`
|
|{awk,sed,perl}-fanatic flames > /dev/null

Well, with a line like above...  I'm a 'cut' fan.  Try this:  It's a LOT
easier to maintain and manage.  (Smaller on disk too :-)

fgrep BLAH *.[ch] | cut -d: -f1 | sort | uniq > /tmp/123 ; vi /tmp/123

This is not a flame.	This is not a flame.	This is not a flame.
This is not a flame.	This is not a flame.	This is not a flame.

	-Jeff
--
Jeff Beadles		Utek Sustaining Engineering, Tektronix Inc.
jeff@quark.WV.TEK.COM	(or) uunet!tektronix.tek.com!quark.wv!jeff

fmr@cwi.nl (Frank Rahmani) (06/25/89)

> easier to maintain and manage.  (Smaller on disk too :-)
> fgrep BLAH *.[ch] | cut -d: -f1 | sort | uniq > /tmp/123 ; vi /tmp/123
> This is not a flame.	This is not a flame.	This is not a flame.
But this one is!!
Your 'tool' doesn't do anything else than open vi on a list of files
that contain BLAH. Very useless indeed.
What you probably mean is:
#!/bin/sh
fgrep $1 *.[ch] | cut -d: -f1 | sort | uniq > /tmp/123 ; e +/$1 `cat /tmp/123`
which opens one or more files on the line that contains the expression
you are looking for. Pay attention that I'm using 'e' instead of 'vi'.
'E' is an interface for vi (was posted on comp.sources.unix) that
maintains durable history files in the directory where 'e' was started.
So you get a log of what you edited and you can access files exactly
by the same syntax as you are accessing commands from the csh .history
file (which is especially handy when you want to edit multiple files.
An example of '.e':
+/define cgname.c dnetmail.c getoptx.c gnu2coff0.6.apollo.c newconv.c scsidriver.seagate.c shadow.c sixel.c tarmail.c text2ps.c timerdriver.c
+/grep cgname.c
../bin/grepvi

While I'm busy: one more flame!
People are posting their tools to help others. When you are convinced
that _YOUR_ tools are better, test them before posting. I'm grateful
for everything that is poted and _WORKS_, it doesn't have to be the
most clever thing on earth. Sometimes its very handy to have different
tools doing the same thing.
Cheers
fmr@cwi.nl
-- 
It is better never to have been born. But who among us has such luck?
Maintainer's Motto:
	If we can't fix it, it ain't broke.
These opinions are solely mine and in no way reflect those of my employer.  

ralf@b.gp.cs.cmu.edu (Ralf Brown) (06/27/89)

In article <130@tridom.uucp> wht@tridom.uucp (Warren Tucker) writes:
}This quickie collects the filenames produced by grep output
}while passing the output oin to stdout.  I wrote it to help
}me build a list of filenames to edit containing a certain string:

At least on BSD Unix, the -l flag on {,e,f}grep does the same thing except
for sorting the output if the file list given to grep is not alphabetical.
-- 
{harvard,uunet,ucbvax}!b.gp.cs.cmu.edu!ralf -=-=- AT&T: (412)268-3053 (school) 
ARPA: RALF@B.GP.CS.CMU.EDU |"Tolerance means excusing the mistakes others make.
FIDO: Ralf Brown at 129/31 | Tact means not noticing them." --Arthur Schnitzler
BITnet: RALF%B.GP.CS.CMU.EDU@CMUCCVMA -=-=- DISCLAIMER? I claimed something?
-- 

det@hawkmoon.MN.ORG (Derek E. Terveer) (06/28/89)

In article <130@tridom.uucp>, wht@tridom.uucp (Warren Tucker) writes:
> I wrote it to help me build a list of filenames to edit containing a certain
> string: 
>     fgrep BLAH *.[ch] | cgname /tmp/123 
>     vi `cat /tmp/123`

I don't suppose that either the ksh or sh constructs that follow would be
suitable replacements for this?

ksh$ vi $(grep -l BLAH  *.[ch])


sh$ vi `grep -l BLAH  *.[ch]`
-- 
Derek Terveer 	    det@hawkmoon.MN.ORG || ..!uunet!rosevax!elric!hawkmoon!det
		    w(612)681-6986   h(612)688-0667

"A proper king is crowned" -- Thomas B. Costain

det@hawkmoon.MN.ORG (Derek E. Terveer) (06/28/89)

In article <929@sering.cwi.nl>, fmr@cwi.nl (Frank Rahmani) writes:
> #!/bin/sh
> fgrep $1 *.[ch] | cut -d: -f1 | sort | uniq > /tmp/123 ; e +/$1 `cat /tmp/123`

This seems kind of long....

> 'E' is an interface for vi (was posted on comp.sources.unix) that
> maintains durable history files in the directory where 'e' was started.

One very easy way of remembering the last set of files edited by vi (NOT
serveral sets, but just the last one) is to use the ksh alias:

alias e=". /usr/local/e"

where /usr/local/e (for example) is:

vi $*
-- 
Derek Terveer 	    det@hawkmoon.MN.ORG || ..!uunet!rosevax!elric!hawkmoon!det
		    w(612)681-6986   h(612)688-0667

"A proper king is crowned" -- Thomas B. Costain

guy@auspex.auspex.com (Guy Harris) (06/29/89)

>At least on BSD Unix, the -l flag on {,e,f}grep does the same thing except
>for sorting the output if the file list given to grep is not alphabetical.

I think it does so on every version of UNIX since V7; if the file list
is constructed from a "*" or "?" pattern, the shells with which I'm
familiar will sort it.

Is there something that "cgname" does that just using "-l" doesn't?