-4

I am trying to add recursive support to my filegrep script.

For some reason this does not work as expected:

RECURSIVE_MODE=off

# iterate over args
for ARG in "$@"
do
    if [ -d "$ARG" ] && [ $RECURSIVE_MODE = on ] ; then
        # recursive call
        $0 $GREP_ARGS $ARG/*
    elif [ -f "$ARG" ]; then
        filecat "$ARG" | grep $GREP_ARGS | sed "s#^#$ARG: #"
    else
        [ "$ARG" = "-r" ] && RECURSIVE_MODE=on
        # append to the current grep args
        GREP_ARGS="$GREP_ARGS $ARG"
    fi
done

I'd like to avoid using functions in this case for better readability.

EDIT: the script should work like this:

for each passed arg:

  • if the current arg is a directory, check if recursive mode is enabled and if yes do the recursive call;
  • else if the current arg is a file, call grep with the current pattern;
  • else assume the current arg is a grep pattern or a grep switch and append it to the current $GREP_ARGS list.

Maybe this is not completely reliable, but it works fine for me as a replacement for zgrep, pdfgrep, etc.

4
  • Instead of writing a script like this, you would be better off learning how regexps work (hint: to grep for multiple alternate patterns, use | in extended regexps or \| in basic RE), as well as the available command-line options of grep (e.g. -r for recursing a directory). For example: e.g. grep -E -r 'pattern1|pattern2|pattern3|...|patternN' /path/to/directory/. Also worth noting is that grep already knows how to deal with multiple file or dir arguments. Your wrapper script is entirely superfluous - it doesn't do anything that grep doesn't already do. Read man grep.
    – cas
    Commented May 21, 2016 at 5:52
  • This has nothing to do with combining multiple patterns. Also grep cannot parse binary files natively (that's why there are wrappers like zgrep, pdfgrep, etc.).
    – eadmaster
    Commented May 22, 2016 at 5:30
  • What does the # append to the query pattern comment mean, then? zgrep may not understand grep's -r option, but that's what find ... -exec is for. BTW, pdfgrep isn't a wrapper around grep, it's a stand-alone program. My point, however, was that by not bothering to learn to use existing tools, you are making things much more difficult for yourself than they need to be and, worse, re-inventing those tools poorly.
    – cas
    Commented May 22, 2016 at 6:06
  • I've added a description of the code to (hopefully) make more clear how it works. I've also renamed $PATTERN to GREP_ARGS to avoid confusion.
    – eadmaster
    Commented May 22, 2016 at 6:56

2 Answers 2

0

Try using the -H option to grep:

   -H, --with-filename
          Print the filename for each match.

So instead of calling your script, just do:

grep -H PATTERN [FILE...]

Also, it's a good idea to check the man page for the tool you are using before you attempt writing a wrapper script. For common Unix tool, the simple options you want are nearly always built into the tool already.

6
  • the purpose of the script is not just adding the filename: prefix. It is made as a companion to filecat, to grep in any filetype (something that regular grep cannot do)
    – eadmaster
    Commented May 21, 2016 at 3:19
  • @eadmaster, that's terrible. You're using filenames to tell you the type of file. That's unreliable and a bad idea. Why not just use file, or better yet, just use zgrep directly? Again, read the manuals because you don't need to reinvent the wheel. (And if you do, at least make it round.)
    – Wildcard
    Commented May 21, 2016 at 4:43
  • ‘zgrep‘ only supports some archive types and it is a crappy wrapper just like mine. ’filegrep’ supports many different filetypes instead. I agree the filenames are not 100% reliable , btw in some cases ‘file’ is not helpful too (e.g. with odt files).
    – eadmaster
    Commented May 21, 2016 at 11:07
  • @eadmaster, file *.odt on my box returns OpenDocument Text quite reliably on my system—how is that not helpful?
    – Wildcard
    Commented May 21, 2016 at 11:25
  • 1
    @eadmaster, when you reach the point where you are trying to implement recursion in a shell script, you need to review your architectural decisions. More bluntly and assertively: There is no real-life use case where the best real-life answer is a recursive shell script. Best of luck to you, though.
    – Wildcard
    Commented May 22, 2016 at 7:40
0

I've finally found the problem was that grep with the -r switch ignores stdin and search in the current working directory instead. To force stdin reading, i've just added a -:

filecat "$ARG" | grep $GREP_ARGS - | sed "s#^#$ARG: #"

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.