Skip to content

Instantly share code, notes, and snippets.

@kshenoy
Last active December 15, 2018 01:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kshenoy/d2d1c7b19eafb043d36239264e758b62 to your computer and use it in GitHub Desktop.
Save kshenoy/d2d1c7b19eafb043d36239264e758b62 to your computer and use it in GitHub Desktop.
Wrapper around ripgrep which adds a --files-from option similar to ack
#!/usr/bin/env bash
#
# Provides a --files-from option: rgf --files-from=[-|FILELIST]
# The list of files to be searched is specified in FILELIST and must be separated by newlines.
# If FILELIST is "-", the list is loaded from standard input.
# This option may be specified multiple times.
#
# Note that this affects how the -t option is applied. When --files-from is specified,
# -t is used to filter the list of files and then ripgrep searches for PATTERN on the list of filtered files
#
# * rgf --files-from=FILELIST PATTERN
# - Search for PATTERN in all files specified in FILELIST
#
# * cat FILELIST | rgf --files-from=- PATTERN
# rgf --files-from=- PATTERN < FILELIST
# - Search for PATTERN in all files specified in FILELIST
#
# * rgf --files-from=- -tFILETYPE PATTERN < FILELIST
# - Filter FILELIST for all files of type FILETYPE and then search for PATTERN on the filtered output
re=\(-h\|--help\)\\b
if [[ "$*" =~ $re ]]; then
command rg "$@"
echo "
Options added by rgf:
--files-from=FILE The list of files to be searched is specified in FILE (similar to ack)
The list of files must be separated by newlines.
If FILE is "-", the list is loaded from standard input.
When used together with --type=TYPE, files specified in FILE
are filtered by TYPE and ripgrep is then run on the filtered output"
exit 0
elif [[ ! "$*" =~ '--files-from' ]]; then
command rg "$@"
exit $!
fi
local _ft_filt=()
local _flist=()
local _rg_opts=()
while (( $# > 0 )); do
if [[ "$1" =~ '--files-from=' ]]; then
local _f=$(sed 's/--files-from=//' <<< "$1")
_flist+=("$_f")
elif [[ "$1" =~ '--files-from' ]]; then
shift
_flist+=("$1")
elif [[ "$1" =~ [^-]-t[[:alpha:]]+ ]]; then
_ft_filt+=($(sed -s 's/^-t//' <<< "$1"))
elif [[ "$1" == "--type" ]]; then
shift
_ft_filt+=("$1")
else
_rg_opts+=("$1")
fi
shift
done
# echo "FList: ${_flist[@]}"
# echo "Types: ${_ft_filt[@]}"
# echo "rg Opts: ${_rg_opts[@]}"
# Compile list of filetypes to filter filelist by
local _ft_pat=""
for _ft in "${_ft_filt[@]}"; do
_ft_pat="${_ft_pat}|$(command rg --type-list | command rg "^$_ft" | cut -d: -f2 | tr -d '*.{ }' | tr ',' '|')"
done
# Remove the leading |
_ft_pat=${_ft_pat#|}
# echo "FileType Pattern: $_ft_pat"
# Finally search for PATTERN on all the files
for _f in ${_flist[@]}; do
cat "$_f"
done | command xargs -d '\n' rg "${_rg_opts[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment