Oreore grep

The grep command is not friendly

A "grep" command that searches for a string in a file. I think it's used quite often, but it's not very kind. It's too gentle and tends to be used with the "find" command. For "find", it tends to make the command line long, so I thought I should complete it with a shell script.

First, determine the default state.

That's why I will implement it.

Optional processing

Speaking of option processing in bash, it is "getopts", but one of the drawbacks is that "options cannot be specified after arguments other than options". However, when getopts comes up with an invalid option, it just stops processing there and it is properly stored in the option argument. So

  1. Use getopts to run a loop and perform optional processing
  2. When exiting the loop, "shift" by the number of processed arguments (not the number of options) However, if no option is specified before the argument other than the option, this number is "0", so only one is "shifted".
  3. Extract "$ 1" as an argument
  4. If "$ 1" is empty, option processing ends

You can mix options and non-option arguments.

Target directory

When grep, most of the files in the directory are targeted, so basically specify the file as "" (wildcard). If no directory is specified, the "" in the current directory is targeted, and if a directory is specified, the "*" in that directory is targeted. However, since it is convenient to be able to specify only the file type, we have made it possible to specify the "extension".

script

And here is the result.

#!/usr/bin/env bash

CMD=`basename $0`

#=============================================================================
# error handler
#Error handling
#=============================================================================
function error() {
  case ${1} in
    [12] )
      echo "Usage:"
      echo "$CMD [-r] [-e ext] [other grep option] search_string [search_directory]"
      echo "-r    : Recursive"
      echo "-e ext: Limits the search to files with the specified extension."
      echo ""
      ;;
    [34] )
      echo "require option parameter."
      echo ""
      ;;
    [5] )
      echo "invalid option - '${2}'"
      echo ""
      ;;
  esac
  exit
}

#=============================================================================
# option procedure
#Optional control
#=============================================================================
function optproc() {
  local OPT OPTARG
  OPT=$1
  OPTARG=$2

  case $OPT in
    [e] )
      if [ -z "$OPTARG" ] || [ ${OPTARG:0:1} = "-" ]; then
        error 3
      else
        OPTION="$OPTION --include *.$OPTARG"
      fi
      ;;
    [r] )
      RECURSIVE="-R"
      TARGET=""
      ;;
    [C] )
      if [ -z "$OPTARG" ] || [ ${OPTARG:0:1} = "-" ]; then
        error 4
      else
        OPTION="$OPTION -C$OPTARG"
      fi
      ;;
    [\?] )
      error 5 $OPTARG
      ;;
    [:] )
      ;;
    * )
      OPTION="$OPTION -$OPT"
      ;;
  esac
}

#=============================================================================
# main procedure
#Main processing
#=============================================================================

#---------------------------
# exec without option
#Run without options
#---------------------------
if [ -z "${1}" ]; then
  error 1
fi

#---------------------------
# variable
#variable
#---------------------------
COMMAND="/usr/bin/env grep"
OPTION="--color=auto -Isn"
RECURSIVE=""
TARGET="*"
SEARCH=""

#---------------------------
# option loop
#Optional loop
#---------------------------
arg="-"
argarr=()

#---------------------------
# valid option
#Valid options
#---------------------------
option=":lvire:C:VcLo"
IFS=$'\n'

while [ ! -z $arg ]; do
  while getopts $option OPT; do
    optproc $OPT $OPTARG
  done

  num="$(($OPTIND-1))"
  shift $num
  arg=$1

  if [ ! -z "$arg" ]; then
    argarr+=($arg)
    OPTIND=1
    shift
  fi

done

SEARCH=${argarr[0]}
if [ -z $SEARCH ]; then
  error 4
fi
num=${#argarr[*]}
DIRTMP=""
for i in $(seq $num); do
  argstr=${argarr[$i]}
  if [ ! -z "$argstr" ]; then
    DIRTMP="$DIRTMP $argstr"
  fi
done

IFS=$'  '

if [ ! -z "$DIRTMP" ]; then
  DIRECTORY=${DIRTMP%/}
  TARGET="$DIRECTORY/$TARGET"
fi

$COMMAND $SEARCH $RECURSIVE $OPTION $TARGET

It's quite versatile, so please use it as a template for shell scripts.

Recommended Posts

Oreore grep
grep command
Origin of grep