Situation: You need to search for multiple items that may be in a config file. Like multiple ip addresses that you are going to add to an existing config file to make sure you are not duplicating rules.

You could just run multiple greps to check for each ip individually OR you could use a single grep statement!

# 'iplist' is a file containing ip addresses

--$ grep '192.168.0.154\|192.168.0.111\|192.168.1.1' iplist 
192.168.0.111
192.168.0.154

Running the grep on iplist nets us 2 hits. Now, in this example, it's easy to track which search term does not appear in the results, but as it scales in size it can become a headache to write the search and read the results.

Enter MultiGrep. MultiGrep is a simple bash script I hacked together. In its current state, it can take a variable number of command line arguments, sanitize them, then pass them to grep.

#!/bin/bash - 
#===============================================================================
#
#          FILE: multigrep.sh
# 
#         USAGE: ./multigrep.sh term1 term2 termX /path/to/file
# 
#   DESCRIPTION: 
# 
#       OPTIONS: ---
#  REQUIREMENTS: ---
#          BUGS: ---
#         NOTES: ---
#        AUTHOR: Micheal Quinn
#  ORGANIZATION:
#       CREATED: 12/11/2012 02:01:53 PM CST
#      REVISION:  0.1
#===============================================================================

#-------------------------------------------------------------------------------
#  Arguments and Varibles 
#-------------------------------------------------------------------------------
ARGS=("${@}")
ELEMENTS=${#ARGS[@]}
LAST=`expr $ELEMENTS - 2`
FILE=`expr $ELEMENTS - 1`
	if [[ "$ELEMENTS" -gt "0" ]]; then
			echo "Great Job!"
		else
			echo "No Args!"
			exit
	fi

#-------------------------------------------------------------------------------
#  Functions
#-------------------------------------------------------------------------------
sanitize(){
# Loop for adding \| to arguments and differentiating between args and file
	for index in ${!ARGS[*]}
	do
		if [[ "$index" == "$FILE" ]]
			then
				SFILE="${ARGS[$index]}"
		elif [[ "$index" == "$LAST" ]]
			then
				SARGS[$index]="${ARGS[$index]}"
		else
			SARGS[$index]="${ARGS[$index]}\|"
		fi
	done
# Remove witespace from output of the array print echo
clean=`echo ${SARGS[*]} | sed -e 's/\s//g'`

}

main(){
	sanitize
	grep -wi --color $${clean} $SFILE
}

main

At the moment, I only have the input sanitized and passed to grep. This is fine with small amounts of search terms, but will get confusing the larger that list grows. I plan to update it to run a grep for each term. I know that this will make the sanitation of the search terms useless, but I'm all about the output. That is, I'd like to see which terms don't show up as well and right now, the only way I can think to do that is multiple grep calls.