Exercism/bash/grep/grep.sh

59 lines
1.6 KiB
Bash

#!/usr/bin/env bash
# parsing CLI options
while getopts :nlivx option; do
case "$option" in
# include line numbers in output
n) linenr=1 ;;
# only file names containing matching lines are printed
l) filename=1 ;;
# case insentivity
i) shopt -s nocasematch ;;
# matching lines are inverted (i.e., lines that do not match)
v) invert=1 ;;
# pattern should match whole line
x) entire=1 ;;
# other options are invalid and exit
\?) echo Invalid option.; exit 1;;
esac
done
# shifts the command-line arguments so that the remaining arguments
# are just the pattern and the files to search in
shift $((OPTIND-1))
pattern=$1
shift
files=( "$@" )
# if entire is set to 1, modifies the pattern to match the entire line
# by anchoring it with ^ (beginning of line) and $ (end of line)
(( entire )) && pattern="^$pattern$"
for file in "${files[@]}"; do
count=0
while read -r line
do
(( count++ ))
out=
if (( invert )); then
! [[ ${line} =~ ${pattern} ]] && out="$line"
else
[[ ${line} =~ ${pattern} ]] && out="$line"
fi
# if filename is set to 1, prints the file name and breaks out
# of the loop after the first matching line in each file
if (( filename )) && [[ -n $out ]]; then
echo $file;
break;
fi
if (( linenr )) && [[ -n $out ]]; then
out="$count":$out;
fi
if (( ${#files[@]} > 1 )) && [[ -n $out ]]; then
out="$file":$out;
fi
[[ -n $out ]] && echo $out;
done < "$file"
done
exit 0