HP3000-L Archives

February 2003, Week 3

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Tom Emerson <[log in to unmask]>
Reply To:
Tom Emerson <[log in to unmask]>
Date:
Fri, 21 Feb 2003 07:58:43 -0800
Content-Type:
text/plain
Parts/Attachments:
text/plain (99 lines)
On Thursday 20 February 2003 5:45 pm, VANCE,JEFF (HP-Cupertino,ex1) wrote:
> So, if you have some script examples that you find really
> useful and are willing to share, or if you have a problem
> that you'd like to solve with a CI script, please let me know.

Here's one my Linux user group helped me with yesterday:

problem: MPEX doesn't run under linux, and "I'm spoiled" :)
I wanted to search for a certain line in a file [i.e., a "grep" operation] but
I only wanted to search files that contained a DIFFERENT string on a
different line.  Under MPEX, this would be done using the "FCONTAINS()"
function as part of the fileset qualifier.

[aside: yes, I know this isn't pure MPE scripting, and likewise this isn't
even CI.PUB.SYS scripting, it's actually a "shell" script/command, but just
because it isn't "CI.PUB", it doesn't mean you should avoid the tool...]

looking at the grep options in the manpage, I found a couple of useful
options:

   -l [lowercase "L"]: return only the FILENAME, stop on the first match
   -h: strip the filename from the output if multiple files were specified on
the command line.  (I used this parameter on the final output because I was
searching e-mails in a "Maildir" folder, the filenames of which are simply
long numeric strings with commas and colons as part of the FILENAME, things
like "1045079974.9205.8Xcj:2,S")

So, at the outset, the command:

   tom@bigbro:~> grep -h target `grep -l qualifier *`

will search all files in the current directory (*) that contain the string
"qualifier", and print only those lines that contain the string "target".
Note that the secong grep command is enclosed with "back-ticks" [left of the
number 1 on most keyboards]

There is a tiny problem with this, however: if the string "qualifier" doesn't
appear in ANY of the files, then the results of the embedded "grep" is a NULL
result, and the first grep command acts as if you didn't specify any files,
i.e., it searched STDIN...  [hangs until you press control-C or control-D]

Some solutions to avoid this:

   grep -h target `grep -l qualifier *` /dev/null
   grep -h target `grep -l qualifier *` <EOF    [note: untested]
   files=`grep -l qualifier` && grep -h target $files

This may take a bit of explaining.  here is the writeup from the guy that gave
me this tip:
=====
The above might do it.  The && ands the exit status of the two grep
commands.  If grep doesn't find anything it returns a false exit status.
(1 for bash --inverted logic).  If the first grep doesn't find anything
then there is no point of checking the exit status of the second grep
since an "and" statement is false if the first argument is false.  Thus
the second grep is never executed due to the "short circuit" method of
anding.  One can use || in a like manner for "or".  Perhaps the exit
status of the first argument of && is based on the = assignment, but if
"grep -l ..." fails then it may consider that = has failed too.  At
least it seems to work that way when I tried it out.  One could enclose
the two arguments of && in {}s to make it clearer what we're anding.
=====

However, the one I ended up going with is this:

   tom@bigbro:~> grep -l qualifier * | xargs grep -h target

this makes use of another shell utility called "xargs" -- basically, this
takes each line of input [from stdin] and supplies it as an argument to the
command(s) supplied in the command line.  From the GNU manpage on xargs:

     This  manual  page  documents  the GNU version of xargs.  xargs reads
     arguments from the standard input, delimited by blanks (which can be
     protected with double or single quotes or a backslash) or newlines, and
     executes the command (default is /bin/echo) one or more times with  any
     initial-arguments  followed by arguments read from standard input.  Blank
     lines on the standard input are ignored.

To turn this into an actual "command script", you need to use placeholders for
target and qualifier like this:

     tom@bigbro:~/bin> cat grepif
     grep -l "$1" * | xargs grep -h "$2"

I think you can replace the * with $3 so you can specify filesets other than
"everything" on the initial command [haven't tried it, however most of the
time I expect to search all files in the current dir anyway]

Of course, the usefullness of this set of commands is predicated on grep
honoring the "-l" parameter under HP's shell for MPE/iX, and secondly the
existance of "xargs" under the shell as well [or you can use one of the other
syntaxes suggested]

--
Yet another Blog: http://osnut.homelinux.net

* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *

ATOM RSS1 RSS2