bfg - find and grep files using boolean expressions.


version 0.06


This program combines the power of three Unix tools (in their GNU versions): bool, find and grep to provide a way to search by filenames and/or by file contents using boolean expressions. Internaly, all boolean expressions with regexps/strings are translated into mathematical expressions and the Perl's interpreter itself is used to validade and evaluate these expressions.

Complex searches using grep are very painful and bool have lots of limitations and complex escape rules. bfg simplify these searches by using more clear syntax and better performance in some cases.

For example, to search

    first AND second AND third AND fourth AND NOT fifth

in filenames, and the same expression in file contents using find and grep, you need do:

    find . \
        -type f \
        -name '*first*' -a \
        -name '*second*' -a \
        -name '*third*' -a \
        -name '*fourth*' -a \
        -not -name '*fifth*' \
        -print0 |
    xargs grep -F -l 'first' |
    tr '\n' |
    xargs grep -F -l 'second' |
    tr '\n' |
    xargs grep -F -l 'third' |
    tr '\n' |
    xargs grep -F -l 'fourth' |
    tr '\n' |
    xargs grep -F -l -v 'fifth'

Using bfg you can sumarize this to:

    bfg -t literal -f \
    first AND second AND third AND fourth AND NOT fifth \
    -F -m \
    first AND second AND third AND fourth AND NOT fifth

About Boolean Expressions

In the context of this program, a Boolean Expression is a composite of OPERANDS, OPERATORS and GROUPS.

An OPERAND is a string representing a literal text or a regular expression. It can be delimited by slashes like ed, sed or vim.

An OPERATOR can be AND, OR or NOT, delimited by white spaces. The following composition of operators are valid too: AND NOT, OR NOT, NOT NOT NOT ... Operators are case insensitive.

A GROUP is a sub expression delimite by parentheses used to define a set of sub conditions to match.

Any expression valid in program languages are valid here.


    bfg [ -m <EXPR>]
    bfg [-F|-i|[-w|-x]] [-m <EXPR>]
    bfg [-D <DIR1 [DIR2 [DIR3]]>] [-t <literal|glob|regexp>] [-I <0|1>] -f <EXPR>
    bfg [-t <literal|glob|regexp>] [-I <0|1>] -f <EXPR> -m <EXPR>
    bfg [-T <filename|-|STDIN> [-d <char>]] [-F|-i|[-w|-x]] -m <EXPR>

    [ --files-from         | -T ]    file name, "-" or stdin.
    [ --files-delim        | -d ]    file names' character separator.
    [ --file-expr          | -f ]    boolean expr to file names.
    [ --find-type          | -t ]    regexp (default), literal or glob.
    [ --find-ignore-case   | -I ]    ignore find operands' case.
    [ --directory          | -D ]    where to search for files.
    [ --match-expr         | -m ]    boolean expr to file contents.
    [ --fixed-strings      | -F ]    operands as literal strings.
    [ --ignore-case        | -i ]    ignore case of operands.
    [ --line-regexp        | -x ]    interpret operands as whole lines.
    [ --word-regexp        | -w ]    interpret operands as whole words.
    [ --glob-regexp        | -g ]    operands as shell patterns.
    [ --files-with-matches | -l ]    show only filenames.
    [ --slash-as-delim     | -s ]    slashes delimit operands.


"find" options

  • --files-from, -T

    Get file names from a file or from Standard Input. Valid forms to express STDIN are hyphen ou word "stdin" (the case is ignored). This option works like -T from gnu tar.

  • --files-delim, -d

    Specify string separator of file names when --files-from, -T is given. This option can receive a NULL character if written as \0 (like -0 option from gnu xargs.

  • --file-expr, -f

    Specify the boolean expression to search in file names. Any boolean expression is valid.

  • --find-type, -t

    Determines if operands of --file-expr, -f are interpreted as literal strings, glob patterns or regular expressions. The default is regular expressions.

  • --find-ignore-case, -I

    Determines if case of operand of --file-expr, -f are relevant or no. Default is yes (0). More or less like -iregex and -iname options from gnu find.

  • --directory, -D

    A white space list of directories to search for files. This switch can be declared one time for each directory.

"grep" options

  • --match-expr, -m

    Specify the boolean expression to search in file contents. Any boolean expression is valid.

  • --fixed-strings, -F

    Interprets the operands of --match-expr as literal strings. Like -F option from gnu grep.

  • --ignore-case, -i

    Ignore or no the case operands' case letters of --match-expr option.

  • --line-regexp, -x

    Interprets each operand of --match-expr as a whole line. Like -x option from gnu grep.

  • --word-regexp, -w

    Interprets each operand of --match-expr as a whole word*. Like -w option from gnu grep.

    *word here is regexp's context.

  • --glob-regexp, -g

    Interprets each operand of --match-expr as shell patterns.

  • --files-with-matches, -l

    Show only filenames.

  • --slash-as-delim, -s

    Inhibt operators and parentheses interpretation insid slashes. To use literal slashes, escape them with a backslash.


"Finding" Perl files

All these options are equivalents:

    $ bfg -I -f '\.pl$ OR \.pm$ OR \.t$ OR \.pod$'
    $ bfg -I -f '/\.(?:p[lm]|t|pod)$/'
    $ bfg -I -f '/\.(?:[Pp][LlMm]|Tt|[Pp][Oo][Dd])$/'
    $ bfg -I -f '\.pl$|\.pm$|\.t$|\.pod$'


AND operator

 foo AND bar

    $ bfg -m foo AND bar
    $ bfg -m '/(?:foo|bar)/'
    $ bfg -m 'foo|bar'

Operands composed by operators or parentheses

If you want search strings with any operator or parentheses, you need delimiter your pattern with slashes (and set option --op-delimiters). Like in:

    /foo OR bar/

This example matches whole string foo or bar but not matches strings foo or bar separately.


Ronaldo Ferreira de Lima aka jimmy <jimmy at gmail>.


  • App::BoolFindGrep.