Solution to grep in bash
This commit is contained in:
58
bash/grep/grep.sh
Normal file
58
bash/grep/grep.sh
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user