Reputation: 38564
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
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
Reputation: 31708
Have a look at the findrepo script which may give you some pointers
Upvotes: 0
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
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
Reputation: 20667
The best solution is stated above, but try putting your statement in back ticks:
`grep ...`
Upvotes: 1
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