Searching Files for Text Strings
In the past, I’ve posted a couple of versions of this script in Bash and Korn shell. Here’s a much-expanded and improved Bash version. The script will take your input and look for files containing the specified text string. You have an option of specifying file type, directory depth, modification time and other parameters to narrow down your search. This script will prove useful for making system and application configuration changes.
#!/bin/bash # 2014 KrazyWorks.com this_script=$0 configure() { this_time=$(date +'%Y-%m-%d_%H%M%S') this_time_db=$(date +'%Y-%m-%d %H:%M:%S') this_host=$(hostname | awk -F'.' '{print $1}') this_hostid=$(hostid) maxsize_mb=10 tail_lines=5 random=$(echo "`expr ${RANDOM}${RANDOM} % 100000`+1"|bc -l) od="/tmp" ofn="search_string_${random}_${this_time}_${this_host}_${this_hostid}_tmp.txt" of="${od}/${ofn}" if [ -f "${of}" ] ; then /bin/rm -f "${of}" ; fi touch "${of}" ; chmod 600 "${of}" whiptailstatus=$(which whiptail > /dev/null 2>&1 ; echo $?) } get_search_string() { if [ ${whiptailstatus} -eq 0 ] then search_string=$(whiptail --inputbox "Enter search string:" 8 78 --title "Search Dialog" 3>&1 1>&2 2>&3) else echo -n "Enter search string: " read search_string fi if [ -z "${search_string}" ] then echo "Search string cannot be null" exit 1 fi } get_search_dir() { if [ ${whiptailstatus} -eq 0 ] then search_dir=$(whiptail --inputbox "Enter search directory:" 8 78 `pwd` --title "Search Dialog" 3>&1 1>&2 2>&3) else echo -n "Enter directory to search [`pwd`]: " read search_dir fi if [ -z "${search_dir}" ] then search_dir=$(pwd) else if [ ! -d "${search_dir}" ] then echo "Directory not found: ${search_dir}" exit 1 fi fi } get_dir_depth() { if [ ${whiptailstatus} -eq 0 ] then dir_depth=$(whiptail --inputbox "Directory depth limit:" 8 78 --title "Search Dialog" 3>&1 1>&2 2>&3) else echo -n "Directory depth limit [unlimited]: " read dir_depth fi if [ -z "${dir_depth}" ] then dir_depth=64000 fi } get_file_name() { if [ ${whiptailstatus} -eq 0 ] then file_name=$(whiptail --inputbox "Enter partial filename:" 8 78 * --title "Search Dialog" 3>&1 1>&2 2>&3) else echo -n "Enter partial filename [*]: " read file_name fi if [ -z "${file_name}" ] then file_name="*" fi } get_file_age() { if [ ${whiptailstatus} -eq 0 ] then mod_time=$(whiptail --inputbox "Enter maximum file age:" 8 78 --title "Search Dialog" 3>&1 1>&2 2>&3) else echo -n "Enter maximum file age [unlimited]: " read mod_time fi if [ -z ${mod_time} ] then mod_time=14600 elif ! [[ "${mod_time}" =~ ^[0-9]+$ ]] then echo "File age must be an integer" exit 1 fi } get_file_type() { if [ ${whiptailstatus} -eq 0 ] then file_type_search=$(whiptail --menu "Specify types of files to search:" --title "Search Dialog" 20 78 16 "1" "Only search ASCII files" "2" "Search all files" 3>&1 1>&2 2>&3) else echo -n "Specify types of files to search [text/all]: " read file_type fi } run_search_ascii() { i=1 ; j=0 ; k=0 find "${search_dir}" -maxdepth ${dir_depth} -type f -iname "*${file_name}*" -mtime -${mod_time} -print | while read line do if [ `file "${line}" | egrep -ic "POSIX|ASCII"` -eq 1 ] && [ -r "${line}" ] then clear echo "Found: ${j}" echo "-----------------------------------" if [ -r "${of}" ] then if [ ${j} -gt ${tail_lines} ] ; then echo "..." ; fi tail -${tail_lines} "${of}" | while read line3 do (( k = k + 1 )) echo -e "${k}:t${line3}" done fi echo "Searching (${i}): ${line}" (( i = i + 1 )) if [ `egrep -ic "${search_string}" "${line}"` -gt 0 ] then echo "${line}" >> "${of}" (( j = j + 1 )) fi fi done } run_search_all() { i=1 ; j=0 ; k=0 find "${search_dir}" -maxdepth ${dir_depth} -type f -iname "*${file_name}*" -mtime -${mod_time} -size -${maxsize_mb}M -print | while read line do if [ -r "${line}" ] then clear echo "Found: ${j}" echo "-----------------------------------" if [ -r "${of}" ] then if [ ${j} -gt ${tail_lines} ] ; then echo "..." ; fi tail -${tail_lines} "${of}" | while read line3 do (( k = k + 1 )) echo -e "${k}:t${line3}" done fi echo "Searching (${i}): ${line}" (( i = i + 1 )) if [ `strings "${line}" | egrep -ic "${search_string}"` -gt 0 ] then echo "${line}" >> "${of}" (( j = j + 1 )) fi fi done } show_results() { clear echo "Found `wc -l ${of} | awk '{print $1}'`" if [ -r "${of}" ] then echo "Results are in ${of}" echo "--------------------------------------" echo "" cat "${of}" | while read line2 do echo -ne "${line2}t" ; echo -ne "Modified: " ; stat -c "%y" "${line2}" | awk -F '.' '{print $1}' egrep -i "${search_string}" "${line2}" | tail -${tail_lines} | sed -e "s/^[ t]*/t/" | while read line4 do echo -e "t${line4}" | fold -w `tput cols` | head -1 done if [ `egrep -ic "${search_string}" "${line2}"` -gt ${tail_lines} ] then echo "..." fi echo "" done echo "" fi } # RUNTIME configure get_search_string get_search_dir get_dir_depth get_file_name get_file_type get_file_age if [ ${file_type_search} -eq 1 ] then run_search_ascii elif [ ${file_type_search} -eq 2 ] then run_search_all else exit 1 fi show_results | more