Combine find with xargs and grep to help locate code snippets.

I wrote this one back in 2006. When you need to find program code snippets, a combination of find, with xargs and grep to the rescue. I call if fin, and Fin.

Works like this, say you’re looking for a program code snippet “select from”, you’re not even sure of the case match.
fin select from

If you are sure of the case, and want to get quicker results, use Fin.

Fin select from

The output of these commands is the lines contain the matching pattern, case match or not depending on the command used, fin or Fin. Each line is preceded with the filename and line number.

But what if the collection of files is intermixed with non-ascii files, images, etc. Or even is an SVN directory tree containing lots of SVN control files? And what if the content gets too large to manage? Over the years my fin and Fin command has evolved to handle these kind of problems.

Cutting to the chase, the whole deal boils down to this sequence of commands changed together:

find . ( -type f -o -type l ) | egrep -v '.svn/' | sed -e "s/'/\'/g" | xargs -J % grep -ni "select from" % /dev/null 2> /dev/null | egrep -v "Binary file .* matches"

So this gets a little tiring to type each time. So I packaged the the solution into a script I call fin, Fin is simply a symbolic link to fin, so there’s only one script here.

My script takes some arguments to make it more useful, so I use the bash function definitions:

fin is a function
fin ()
/usr/local/bin/fin --nobinarymatches --nosvn $*

Fin is a function
Fin ()
/usr/local/bin/Fin --nobinarymatches --nosvn $*

The whole script is here:

#!/bin/bash –norc
# File: /usr/local/bin/fin (aka: /usr/local/bin/Fin)
# Author: Frank Koenen
# Purpose: provide a group of file search.
# Install: ( cd /usr/local/bin && ln -s fin Fin )
# Usage: –help option.
# History:
# 27-Apr-06 fhk; Init
# 09-Sep-06 fhk; added SunOS compatibility
# 11-Nov-06 fhk; added lfind and nosvnfind for performance reasons.
# 11-Nov-06 fhk; added fins/Fins logic
# 25-Nov-09 fhk; patched for handle file names containing single-quote chars.
typeset -r ExeName=${0##*/} ; export ExeName

case “${ExeName}” in
“fin”|”fins”) typeset -r i=”i” ;;

# Functions ———————————————–
function lfind {
find . ( -type f -o -type l )

function nosvnfind {
find . ( -type f -o -type l ) | egrep -v ‘.svn/’

# Main —————————————————-
export showbinstoo=1
export findcmd=”lfind”
while [ $# -gt 0 ]; do
case “${1}” in
echo “$ExeName [–help] | [–nobinarymatches] [–nosvn] {pattern}” >&2
–nobinarymatches) export showbinstoo=0 ;;
–nosvn) export findcmd=”nosvnfind” ;;
*) break ;;

case “$(uname -a|tr ‘[A-Z]’ ‘[a-z]’)” in
*’sunos’*|*’freebsd’*) typeset -r tt=sunos ;;
*) typeset -r tt=linux ;;

if (( $showbinstoo == 1 )) ; then
if [ “${tt}x” == “linuxx” ]; then
$findcmd | sed -e “s/’/\’/g” | xargs –replace=”{file}” grep -nH$i “${*}” “{file}”
$findcmd | sed -e “s/’/\’/g” | xargs -J % grep -n$i “${*}” % /dev/null 2> /dev/null
if [ “${tt}x” == “linuxx” ]; then
$findcmd | sed -e “s/’/\’/g” | xargs –replace=”{file}” grep -nH$i “${*}” “{file}” | egrep -v “Binary file .* matches”
$findcmd | sed -e “s/’/\’/g” | xargs -J % grep -n$i “${*}” % /dev/null 2> /dev/null | egrep -v “Binary file .* matches”

exit 0

Lastly, I also defined my f1 command.

f1 is a function
f1 ()
grep -v "^Binary file " | cut -d: -f1 | sort -u

This takes the output of fin or Fin and reduces it down to just the unique set of files that contain the matching pattern. Then I can do things like this:

vim $(fin select from|f1)

to edit all files containing the matching pattern.