Created
September 7, 2023 23:06
-
-
Save akkartik/8ada765dbf7a04613bd04523be5332d2 to your computer and use it in GitHub Desktop.
search -- from the outside in and from the inside out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/zsh | |
# Search a directory for files containing all of the given keywords. | |
DIR=`mktemp -d` | |
ROOT=${ROOT:-.} | |
# generate results for each term in isolation | |
for term in $* | |
do | |
out=`echo $term |sed 's,[/:^*+],_,g'` | |
if echo $term |grep -q '[A-Z]' # all lowercase => case-insensitive search | |
then | |
echo grep -Rl $term $ROOT \> $DIR/$out.list >&2 | |
eval grep -Rl $term $ROOT > $DIR/$out.list | |
else | |
echo grep -Ril $term $ROOT \> $DIR/$out.list >&2 | |
eval grep -Ril $term $ROOT > $DIR/$out.list | |
fi | |
done | |
# generate results containing all terms | |
cat $DIR/*.list |sort |uniq -c |grep " $# " |column 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/zsh | |
# Search a directory for files containing all of the given keywords. | |
# Credit: Kragen Sitaker for the idea of tail recursion using `exec $0` | |
ROOT=${ROOT:-.} | |
# Use absence of "--" to signal the outermost call. | |
# Recursive calls of $0 inside this script will always start with "--" | |
if [[ $1 != "--" ]] | |
then | |
# recursive calls exchange information using null-terminated lines | |
# get rid of nulls in the outermost call | |
# also sort for consistency | |
ROOT="$ROOT" exec $0 -- $* |xargs -n 1 -0 echo |sort | |
exit $? # TODO: Why is this needed?! | |
fi | |
# Only internal calls starting with "--" get to this point. | |
shift # skip the -- | |
if [[ $# -eq 0 ]] | |
then | |
# base case: generate a list of files on stdout | |
exec find "$ROOT" -type f -print0 | |
else | |
# search through the files coming in on stdout for one term, then recurse | |
keyword=$1 | |
shift | |
if echo $keyword |grep -q '[A-Z]' | |
then | |
ROOT="$ROOT" exec $0 -- $* | xargs -0 grep -lZ "$keyword" | |
else | |
ROOT="$ROOT" exec $0 -- $* | xargs -0 grep -ilZ "$keyword" | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Simpler version showing the bug, without
ROOT
or case-insensitive search.