How many times have grep’d a file, and then piped the output in order to grep again, and then piped that again to grep? Sometimes when I am search a file, I could end up piping maybe a dozen times while searching the file. Just for fun, I wanted to write a recursive grep program, rgrep in rust. However, as a first step, I figured I could write it in bash first.
In order to use associated arrays, you must first be using Bash 4, as earlier versions did not have this feature. I wrote this as simply as possible, so there very well could be bugs. I only wanted to write as lean a script as possible for preliminary testing.
rgrep.sh
#!/usr/bin/env bash
# Initialize array for search results
declare -A rloop
# Get array of args
args=($@)
# Get length of args array
arg_len=${#args[@]}
# Exit if too few args are passed
if [[ $arg_len -le 1 ]]
then
echo "Please enter your args, followed by a trailing file to parse"
exit 1
fi
# Get last arg
file=${args[$len-1]}
# Exit if $file does not exist
if [[ ! -e $file ]]
then
echo "Could not access $file"
exit 1
fi
# Get list of args ignoring the last arg
search_terms=${args[@]:0:${arg_len}-1}
# Loop over args
count=0
for i in ${search_terms[@]}
do
if [[ $count == 0 ]]
then
# If we are on the first loop, then grep the file directly
rloop[$count]=$(grep -i $i $file)
else
# Otherwise, grep the previous loop's content
previous_loop=$((count-1))
rloop[$count]=$(echo "${rloop[$previous_loop]}" | grep -i $i)
fi
count=$((count+1))
done
# Display search results
last_loop=$((count-1))
echo "${rloop[$last_loop]}"
Using rgrep.sh, we can search for lines that include the work “and”:
[admin@openbox coding_projects/shell]# ./rgrep.sh and poem.txt
Thou art more lovely and more temperate.
And summer's lease hath all too short a date.
And often is his gold complexion dimmed,
And every fair from fair sometime declines,
This is just a simple implementation of a recursive grep. Next will be me trying to find a way to code this shell script in rust. Hopefully someone will find a use for this code.
Has been tested on OpenBSD 6.5