Moving to Freedom, .Org(on)

findr: a GNU/Unix ‘find’ helper

I’ve been more aggressive lately about creating helper scripts and aliases for common tasks, and I liked this find helper enough to want to share it. I find that I often do filename searches like this:

find -iname "*some_word*"

That’s not so bad to type, but why not make it even easier for my, and maybe your common usage? We might prefer to do something like this:

findr some_word

And assume that we’re looking for a case-insensitive, substring match. And since we love regular expressions, we can work with find’s regex options:

--regextype posix-egrep -iregex

Which is just begging for a helper to do the work for us in standard situations.

Before we look at the script and some examples, here are a few more considerations for our findr command:

findr.sh

(Use this code at your own risk, and use it however you like. To the extent possible, I’m putting this into the public domain.)

#!/bin/bash

 usage="\nfindr.sh: Helper to make regex find commands easier.\n\n"
usage+="  usage: findr.sh [-a] [-p preview mode] [find args] expression\n"
usage+="\t-a\tsearch all filesystems (default is -xdev/-mount)\n"
usage+="\t-p\tpreview mode; just show the resulting find command\n"
usage+="\n\t\t(can't combine params, e.g. -ap)\n"

preview=false
# use "nowarn" to avoid warning if -mount used after -type f, e.g.
xdev=" -nowarn -mount "

while [[ -n "$1" ]]; do
    if [[ $1 == "-h" || $1 == "--help" || $1 == "-help" ]]; then
        echo -e $usage
        exit 0
    elif [[ $1 == "-a" ]]; then
        xdev=""
    elif [[ $1 == "-p" ]]; then
        preview=true
    elif [[ $# -eq 1 ]]; then
        regex=$1
    else
        args+=" $1"
    fi
    shift
done

args+="${xdev}-regextype posix-egrep -iregex"
regex="^.*${regex}[^/]*$"

if [[ "$preview" == "true" ]]; then
    echo "find $args \"$regex\"" >&2
else
    find $args "$regex"
fi

I’ve created in ~/.bash_aliases:

Thus:

findr secret-plans

Becomes:

find -nowarn -mount -regextype posix-egrep -iregex "^.*secret-plans[^/]*$"

You can add other “find” options, like the dir to search:

findr /home/scarpent secret-plans

Or specify the file type:

findr -type f secret-plans

Or whatever other option. The script includes the -nowarn option with -mount, because for example with this command:

find -type f -mount -regextype posix-egrep -iregex "^.*secret-plans[^/]*$"

find will complain about the order of options, and while I appreciate the good intentions and wisdom of the warning, it isn’t a problem for me. (Not until I get burned by missing some other suppressed warning, I guess.)

And you can take advantage of regular expressions! For example, maybe you want to look for the song “Oh, Yeah,” by Yello, and avoid matching on Elton John, Joni Mitchell, or Tony Orlando songs. You can use a word boundary:

findr "yello\b" or findr yello\\b

The find command is loaded with options and my understanding of it is only mildly nuanced, so this may (and will!) break down in many scenarios, but it’s not meant to be a replacement for direct use of find.

It’s just a helper, after all.