#! /bin/sh # ############################################################################# NAME_="sfiles" HTML_="recursively search files for strings" PURPOSE_="recursively search files for strings; list found files in sorted order" SYNOPSIS_="$NAME_ [-hlm] -p \"\" -s +|- -a \"\" [-o \"\"] [-n \"\"]" REQUIRES_="standard GNU commands" VERSION_="1.1" DATE_="2002-06-17; last update: 2005-02-14" AUTHOR_="Dawid Michalczyk " URL_="www.comp.eonworks.com" CATEGORY_="file" PLATFORM_="Linux" SHELL_="bash" DISTRIBUTE_="yes" # ############################################################################# # This program is distributed under the terms of the GNU General Public License # HISTORY: # 2002-06-17 v1.0 # 2005-02-14 v1.1 - complete rewrite # TODO: # - change the file searching arguments to one find argument usage () { echo >&2 "$NAME_ $VERSION_ - $PURPOSE_ Usage: $SYNOPSIS_ Requires: $REQUIRES_ Options: -p, \"\", search file pattern as accepted by find's -name option. No case distinction is made. -s, +|-, file size in bytes; +n for greater then n; -n for less then n; n for exactly n. -a, AND operator. Match files that contain all strings supplied to this argument. No case distinction is made. -o, OR operator. Match files that contain at least one of the strings supplied to this argument. No case distinction is made. -n, NOT operator. Do not match files that contain strings supplied to this argument. No case distinction is made. -w, list files in html format, where each file has a link to it's location -h, usage and options (this help) -m, manual -l, see this script" exit 1 } manual () { echo >&2 " NAME $NAME_ $VERSION_ - $PURPOSE_ SYNOPSIS $SYNOPSIS_ DESCRIPTION $NAME_ is a searching tool for local text files. It recursively searches for specified strings in files. It supports AND, OR and NOT boolean operators. The string search is not case sensitive. The output consists of the sum of each string found in a matched file. The results are sorted by the total AND strings found. An html formatted output is optional for easy location of files using a browser. AUTHOR $AUTHOR_ Suggestions and bug reports are welcome. For updates and more scripts visit $URL_ "; exit 1; } # args check [ $# -eq 0 ] && { echo >&2 missing argument, type $NAME_ -h for help; exit 1; } # tmp file set up tmp_dir=/tmp/${RANDOM}${RANDOM} mkdir $tmp_dir tmp_1=$tmp_dir/tmp.${RANDOM}${RANDOM} # signal trapping and tmp file removal trap 'rm -f $tmp_1; rmdir $tmp_dir >/dev/null 2>&1' 0 trap "exit 1" 1 2 3 15 # var init file_size= file_pattern= and_strings= or_strings= not_strings= html_format= html_header= while getopts whlms:p:a:o:n: options; do case "$options" in s) file_size=$OPTARG ;; p) file_pattern=$OPTARG ;; a) and_strings=($OPTARG) ;; o) or_strings=($OPTARG) ;; n) not_strings=($OPTARG) ;; w) html_format=on ;; h) usage ;; m) manual | more; exit 1 ;; l) more $0; exit 1 ;; \?) echo invalid argument, type $NAME_ -h for help; exit 1 ;; esac done args=$@ shift $(( $OPTIND - 1 )) # arg check [[ $file_pattern ]] || { echo >&2 missing file pattern argument; exit 1; } [[ $file_size ]] || { echo >&2 missing file size argument; exit 1; } [[ $and_strings ]] || { echo >&2 missing option to the -a argument; exit 1; } # main find . -type f -iname "${file_pattern}" -size ${file_size}c | while read file; do # searching for AND strings c=0 total_count=0 for string in ${and_strings[*]}; do count=$(grep -ci $string $file) [ $? != 0 ] && continue 2 result[c]=$(echo ${string}: $count) ((c++)) (( total_count += count )) done # if OR strings are set if [[ $or_strings ]];then # search for OR strings for string in ${or_strings[*]}; do grep -qi $string $file [ $? = 0 ] && or=0 || or=1 done [[ $or == 1 ]] && continue fi # if NOT strings are set if [[ $not_strings ]]; then # search for NOT strings for string in ${not_strings[*]}; do grep -qi $string $file [ $? = 0 ] && continue 2 done fi # printing files that match the search criteria if [[ $html_format ]];then if [[ $html_header ]]; then echo "total: $total_count ${result[*]} file: $file
" >> $tmp_1 else echo "$args $(pwd)" echo "dir: $(pwd)
" echo "arg: $args

" echo "search results:

" echo "total: $total_count ${result[*]} file: $file
" >> $tmp_1 html_header=0 fi else echo total: $total_count ${result[*]} file: $file >> $tmp_1 fi done sort -grk 2 $tmp_1