#!/bin/bash
######################################################
# file name: findline #
# find lines in files, recursively in current folder #
######################################################
ME=`basename $0`
showHelp()
{
echo "usage $ME -h"
echo "usage $ME [-i] [-s] [-n] [-c] -e regex_pattern [file_suffix1] [file_suffix2] [...]"
echo "usage $ME [-i] [-s] [-n] [-c] text_pattern [file_suffix1] [file_suffix2] [...]"
echo "usage $ME [-l] [-s] [-i] [-c] -e regex_pattern | text_pattern [file_suffix1] [file_suffix2] [...]"
echo "usage $ME [-l] [-s] [-i] [-c] text_pattern [file_suffix1] [file_suffix2] [...]"
echo "-h: show help"
echo "-i: ignore case"
echo "-s: silence mode, do not show command"
echo "-n: show line number"
echo "-c: exclude comment line, which is start with #"
echo "-e: regex pattern"
echo "-l: list file name only, will use -n by default"
echo "The file suffix is case insensitive"
}
INVALID=1
IGNORE_CASE=1
REGEX=1
SILENCE=1
NUMBER=1
COMMENT=1
LIST=1
# check arguments
while getopts :ilhscne: OPTION
do
case $OPTION in
i) IGNORE_CASE=0
;;
s) SILENCE=0
;;
e) REGEX=0
PATTERN=$OPTARG
;;
n) NUMBER=0
;;
c) COMMENT=0
;;
l) LIST=0
;;
h) showHelp
exit 0
;;
*) INVALID=0
;;
esac
done
# user input invalid arguments
[ $INVALID -eq 0 -o $# -eq 0 ] && showHelp && exit 1
#echo $OPTIND
# shift to pattern arg position
shift `expr $OPTIND - 1`
if [ $REGEX -ne 0 ]
then
PATTERN=$1
fi
# no pattern arg was assigned
[ -z "$PATTERN" ] && showHelp && exit 1
# if no -e was specified, use next args as suffixes
[ $REGEX -ne 0 ] && shift
SUFFIX=$*
# set exec args for options
[ $IGNORE_CASE -eq 0 ] && IGNORE_CASE_ARG="-i"
[ $REGEX -eq 0 ] && REGEX_ARG="-E \"$PATTERN\"" || REGEX_ARG=\"$PATTERN\"
[ $NUMBER -eq 0 ] && NUMBER_ARG=" | nl"
[ $COMMENT -eq 0 ] && COMMENT_ARG=" | grep -E -v '^.+:[0-9]+:\s*#'"
if [ -n "$SUFFIX" ]
then
for VAR in $SUFFIX
do
S=$S"|"$VAR
done
SUFFIX_PATTERN=`echo $S | sed 's/|//'`
SUFFIX_ARG=" | grep -i -E \"\.($SUFFIX_PATTERN‘)\$\""
fi
RET=0
# find command
if [ $LIST -ne 0 ]
then
# show find lines
CMD="find . -print0 -type f -follow -name \"*\" 2>/dev/null | xargs -0 ls -d | awk '{ORS=\"\";print\"'\\''\";print\$0;print\"'\\''\";print\"\\n\"}' $SUFFIX_ARG | xargs grep -n -H $IGNORE_CASE_ARG $REGEX_ARG $COMMENT_ARG $NUMBER_ARG | sort"
else
# show file list
CMD="find . -print0 -type f -follow -name \"*\" 2>/dev/null | xargs -0 ls -d | awk '{ORS=\"\";print\"'\\''\";print\$0;print\"'\\''\";print\"\\n\"}' $SUFFIX_ARG | xargs grep -n -H $IGNORE_CASE_ARG $REGEX_ARG $COMMENT_ARG | grep ":" | cut -d: -f1 | sort -u"
fi
# display find command
[ $SILENCE -eq 0 ] || echo $CMD
if [ $LIST -ne 0 ]
then
# execute show find lines
eval $CMD
else
# execute show file list
FILES=(`eval "$CMD"`)
INDEX=0
while [ $INDEX -lt ${#FILES[*]} ]
do
NO=`expr $INDEX + 1`
echo "$NO. ${FILES[$INDEX]}"
eval "_$NO=${FILES[$INDEX]}"
INDEX=$NO
done
if [ ${#FILES[*]} -gt 0 ]
then
# execute command
echo -e "Input command('\$_n' as file name):\c"
read TMP
if [ -n "$TMP" ]
then
COMMAND="$TMP 2>/dev/null"
eval $COMMAND
fi
fi
fi
RET=$?
exit $RET
######################################################
# file name: findline #
# find lines in files, recursively in current folder #
######################################################
ME=`basename $0`
showHelp()
{
echo "usage $ME -h"
echo "usage $ME [-i] [-s] [-n] [-c] -e regex_pattern [file_suffix1] [file_suffix2] [...]"
echo "usage $ME [-i] [-s] [-n] [-c] text_pattern [file_suffix1] [file_suffix2] [...]"
echo "usage $ME [-l] [-s] [-i] [-c] -e regex_pattern | text_pattern [file_suffix1] [file_suffix2] [...]"
echo "usage $ME [-l] [-s] [-i] [-c] text_pattern [file_suffix1] [file_suffix2] [...]"
echo "-h: show help"
echo "-i: ignore case"
echo "-s: silence mode, do not show command"
echo "-n: show line number"
echo "-c: exclude comment line, which is start with #"
echo "-e: regex pattern"
echo "-l: list file name only, will use -n by default"
echo "The file suffix is case insensitive"
}
INVALID=1
IGNORE_CASE=1
REGEX=1
SILENCE=1
NUMBER=1
COMMENT=1
LIST=1
# check arguments
while getopts :ilhscne: OPTION
do
case $OPTION in
i) IGNORE_CASE=0
;;
s) SILENCE=0
;;
e) REGEX=0
PATTERN=$OPTARG
;;
n) NUMBER=0
;;
c) COMMENT=0
;;
l) LIST=0
;;
h) showHelp
exit 0
;;
*) INVALID=0
;;
esac
done
# user input invalid arguments
[ $INVALID -eq 0 -o $# -eq 0 ] && showHelp && exit 1
#echo $OPTIND
# shift to pattern arg position
shift `expr $OPTIND - 1`
if [ $REGEX -ne 0 ]
then
PATTERN=$1
fi
# no pattern arg was assigned
[ -z "$PATTERN" ] && showHelp && exit 1
# if no -e was specified, use next args as suffixes
[ $REGEX -ne 0 ] && shift
SUFFIX=$*
# set exec args for options
[ $IGNORE_CASE -eq 0 ] && IGNORE_CASE_ARG="-i"
[ $REGEX -eq 0 ] && REGEX_ARG="-E \"$PATTERN\"" || REGEX_ARG=\"$PATTERN\"
[ $NUMBER -eq 0 ] && NUMBER_ARG=" | nl"
[ $COMMENT -eq 0 ] && COMMENT_ARG=" | grep -E -v '^.+:[0-9]+:\s*#'"
if [ -n "$SUFFIX" ]
then
for VAR in $SUFFIX
do
S=$S"|"$VAR
done
SUFFIX_PATTERN=`echo $S | sed 's/|//'`
SUFFIX_ARG=" | grep -i -E \"\.($SUFFIX_PATTERN‘)\$\""
fi
RET=0
# find command
if [ $LIST -ne 0 ]
then
# show find lines
CMD="find . -print0 -type f -follow -name \"*\" 2>/dev/null | xargs -0 ls -d | awk '{ORS=\"\";print\"'\\''\";print\$0;print\"'\\''\";print\"\\n\"}' $SUFFIX_ARG | xargs grep -n -H $IGNORE_CASE_ARG $REGEX_ARG $COMMENT_ARG $NUMBER_ARG | sort"
else
# show file list
CMD="find . -print0 -type f -follow -name \"*\" 2>/dev/null | xargs -0 ls -d | awk '{ORS=\"\";print\"'\\''\";print\$0;print\"'\\''\";print\"\\n\"}' $SUFFIX_ARG | xargs grep -n -H $IGNORE_CASE_ARG $REGEX_ARG $COMMENT_ARG | grep ":" | cut -d: -f1 | sort -u"
fi
# display find command
[ $SILENCE -eq 0 ] || echo $CMD
if [ $LIST -ne 0 ]
then
# execute show find lines
eval $CMD
else
# execute show file list
FILES=(`eval "$CMD"`)
INDEX=0
while [ $INDEX -lt ${#FILES[*]} ]
do
NO=`expr $INDEX + 1`
echo "$NO. ${FILES[$INDEX]}"
eval "_$NO=${FILES[$INDEX]}"
INDEX=$NO
done
if [ ${#FILES[*]} -gt 0 ]
then
# execute command
echo -e "Input command('\$_n' as file name):\c"
read TMP
if [ -n "$TMP" ]
then
COMMAND="$TMP 2>/dev/null"
eval $COMMAND
fi
fi
fi
RET=$?
exit $RET