Carson Myers
Carson Myers

Reputation: 38564

calling grep from a bash script

I'm new to bash scripts (and the *nix shell altogether) but I'm trying to write this script to make grepping a codebase easier.

I have written this

#!/bin/bash
args=("$@");
for arg in args
 grep arg * */* */*/* */*/*/* */*/*/*/*;
done

when I try to run it, this is what happens:

~/Work/richmond $ ./f.sh "\$_REQUEST\['a'\]"
./f.sh: line 4: syntax error near unexpected token `grep'
./f.sh: line 4: `       grep arg * */* */*/* */*/*/* */*/*/*/*;'
~/Work/richmond $

How do I do this properly?

And, I think a more important question is, how can I make grep recurse through subdirectories properly like this?

Any other tips and/or pitfalls with shell scripting and using bash in general would also be appreciated.

Upvotes: 1

Views: 7599

Answers (6)

Roland Illig
Roland Illig

Reputation: 41627

If you just want a better grep and don't want to do anything yourself, use ack, which you can get at http://betterthangrep.com/.

Upvotes: 0

pixelbeat
pixelbeat

Reputation: 31708

Have a look at the findrepo script which may give you some pointers

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 361585

The syntax error is because you're missing do. As for searching recursively if your grep has the -R option you would do:

#!/bin/bash
for arg in "$@"; do
   grep -R "$arg" *
done

Otherwise you could use find:

#!/bin/bash
for arg in "$@"; do
   find . -exec grep "$arg" {} +
done

In the latter example, find will execute grep and replace the {} braces with the file names it finds, starting in the current directory ..

(Notice that I also changed arg to "$arg". You need the dollar sign to get the variable's value, and the quotes tell the shell to treat its value as one big word, even if $arg contains spaces or newlines.)

Upvotes: 9

Jonathan Leffler
Jonathan Leffler

Reputation: 753615

You should use 'find' plus 'xargs' to do the file searching.

for arg in "$@"
do
    find . -type f -print0 | xargs -0 grep "$arg" /dev/null
done

The '-print0' and '-0' options assume you're using GNU grep and ensure that the script works even if there are spaces or other unexpected characters in your path names. Using xargs like this is more efficient than having find execute it for each file; the /dev/null appears in the argument list so grep always reports the name of the file containing the match.

You might decide to simplify life - perhaps - by combining all the searches into one using either egrep or grep -E. An optimization would be to capture the output from find once and then feed that to xargs on each iteration.

Upvotes: 1

Topher Fangio
Topher Fangio

Reputation: 20667

The best solution is stated above, but try putting your statement in back ticks:

`grep ...`

Upvotes: 1

Rob
Rob

Reputation: 755

On recusive grepping:

Depending on your grep version, you can pass -R to your grep command to have it search Recursively (in subdirectories).

Upvotes: 3

Related Questions