Skip to content

Instantly share code, notes, and snippets.

@jonlabelle
Last active March 5, 2021 05:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jonlabelle/5a994499c797e718c5ba4fbda8e55701 to your computer and use it in GitHub Desktop.
Save jonlabelle/5a994499c797e718c5ba4fbda8e55701 to your computer and use it in GitHub Desktop.
Bash script to search file contents (by file extension) for the specified search term. Uses grep under the hood.
#!/usr/bin/env bash
# shellcheck disable=SC2034,SC2086,SC2155,SC2001,SC2048
#
# Search file contents (by file extension) for the specified search term.
#
# grep options:
#
# -i Perform case insensitive matching.
# −r Recursively search subdirectories listed.
# −I Ignore binary files.
# −s Nonexistent and unreadable files are ignored (i.e. their error messages are suppressed).
# -l Only the names of files containing selected lines are written to standard output.
#
# Author.....: Jon LaBelle
# Date.......: November 22, 2018
# Homepage...: <https://jonlabelle.com/snippets/view/shell/search-file-content>
#
set -e
set -o pipefail
readonly SCRIPT_NAME=$(basename "${0}")
SEARCH_TERM=
FILE_EXTENSION=
FILES_WITH_MATCHES=false
VERBOSE=false
log_verbose() {
if [ "$VERBOSE" = "true" ]; then
echo ${1}
fi
}
show_usage() {
echo "Usage: ${SCRIPT_NAME} -t <term> -e <file_extension> [options]"
echo
echo "Search options:"
echo
echo " -t, --search-term <term> the term to search in files for (case insensitive)."
echo " -e, --file-extension <extension> only files with this extension will be searched (w/out leading dot)."
echo " -l, −−files-with-matches only print the matched (relative) file path to stdout."
echo " paths are listed only once per file searched."
echo
echo "Other options:"
echo
echo " -v, --verbose useful for debugging and seeing what's going on under the hood."
echo " -h, --help show this message and exit."
echo
echo "Examples:"
echo
echo " To search C# files containing the term 'thread':"
echo " $ ${SCRIPT_NAME} -t thread -e cs"
echo
echo " To search C# files containing the term 'thread' and print debug information (-v):"
echo " $ ${SCRIPT_NAME} -v -t thread -e cs"
echo
echo " To search C# files containing the term 'Thread()' and only print file name matches (-l):"
echo " $ ${SCRIPT_NAME} -t 'Thread()' -e cs -l"
echo
}
search() {
log_verbose "> Searching '${FILE_EXTENSION}' files for '${SEARCH_TERM}' in '$(pwd)'..."
log_verbose ""
if [ "$FILES_WITH_MATCHES" = "true" ]; then
find . -iname '*.'${FILE_EXTENSION} -type f -exec grep -i -r -I -s -l ''${SEARCH_TERM}'' '{}' \;
else
find . -iname '*.'${FILE_EXTENSION} -type f -exec grep -i -r -I -s ''${SEARCH_TERM}'' '{}' \;
fi
}
main() {
if [[ "$1" = "-h" || "$1" = "--help" || "$1" = "help" || "$1" = "--version" ]]; then
show_usage
exit 0
fi
while (( "$#" )); do
if [[ "$1" = "-t" || "$1" = "--search-term" ]]; then
log_verbose "> Setting search term filter to: '$2'"
SEARCH_TERM=$2
elif [[ "$1" = "-e" || "$1" = "--file-extension" ]]; then
log_verbose "> Setting file extension filter to: '$2'"
FILE_EXTENSION=$2
elif [[ "$1" = "-v" || "$1" = "--verbose" ]]; then
VERBOSE=true
log_verbose "> Verbose mode enabled."
elif [[ "$1" = "-l" || "$1" = "−−files-with-matches" ]]; then
FILES_WITH_MATCHES=true
log_verbose "> Only file matches will be printed to stdout."
fi
shift
done
if [[ -z "$FILE_EXTENSION" || -z "$SEARCH_TERM" ]]; then
echo "Values for both '--search-term' and '--file-extension' are required."
echo "Type '${SCRIPT_NAME} --help' for help information, including usage and examples."
exit 1
fi
search $FILE_EXTENSION $SEARCH_TERM
exit 0
}
if [ "$#" -eq 0 ]; then
show_usage
exit 1
else
main $*
fi
@Abhinav1217
Copy link

Thanks for this script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment