How can I expand arguments to a bash function into a chain of piped commands?

I often find myself doing something like this a lot:

something | grep cat | grep bat | grep rat

when all I recall is that those three words must have occurred somewhere, in some order, in the output of something...Now, i could do something like this:

something | grep '.*cat.*bat.*rat.*'

but that implies ordering (bat appears after cat). As such, I was thinking of adding a bash function to my environment called mgrep which would turn:

mgrep cat bat rat


grep cat | grep bat | grep rat

but I'm not quite sure how to do it (or whether there is an alternative?). One idea would be to for loop over the parameters like so:

while (($#)); do
    grep $1 some_thing > some_thing
cat some_thing

where some_thing is possibly some fifo like when one does >(cmd) in bash but I'm not sure. How would one proceed?


I believe you could generate a pipeline one command at a time, by redirecting stdin at each step. But it's much simpler and cleaner to generate your pipeline as a string and execute it with eval, like this:

CMD="grep '$1' "  # consume the first argument

for arg in "$@"   # Add the rest in a pipeline
  CMD="$CMD | grep '$arg'"
eval $CMD

This will generate a pipeline of greps that always reads from standard input, as in your model. Note that it protects spaces in quoted arguments, so that it works correctly if you write:

mgrep 'the cat' 'the bat' 'the rat'

Thanks to Alexis, this is what I did:

function mgrep() #grep multiple keywords
    while (($#)); do
        CMD="$CMD grep \"$1\" | "
    eval ${CMD%| }

Need Your Help

PHP - Calling a Class Method

php methods

I've been handed a PHP class, and I'm not interested in fully restructuring it. (it works!)

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.