Loading
freq
Neighboring pages...
Offer to run a complex linux command from among those listed in a file in the current directory, .
This facility makes it easy to package common actions in particular contexts. That can be a huge memory aid, preserving a record of the actions I have available in particular contexts, including intricate details of those actions.
Last update: 2021-04-25
#!/bin/bash
# Offer to run a complex command from among those in `./.frequents`
# - A command line parameter is taken as the chosen line's number or label.
# - Otherwise, a consolidated list of comments and commands are presented,
# and a prompt is issued for a line number or label of command to run.
# - In either case the choice is echoed and the command line is evalled.
# - Using eval means the command line can contain multiple commands in a
# pipeline, sequence, with backgrounded components, etc.
# - Lines that begin with a "#" hash mark are taken as commentary and
# labels for the following lines.
# - The comments are presented in the listing but not included in the
# command-numbering count.
# - The comment lines can contain a ":" delimited word, which is used
# as a label for the succeeding command line.
# - The word may not contain any whitespace.
# Copyright Ken Manheimer, ken.manheimer@gmail.com, 2007-2019
# Licensed under Gnu Public License v3,
unset lines
unset comments
unset labels
declare -A labels
arg="$1"
NEWLINE="
"
read_from () {
carry=""
if [ -r "$1" ]; then
exec 3< "$1"
while read curline <&3; do
if [ -n "$carry" ]; then
curline="$carry $curline"
carry=""
fi
case $curline in
*" "\\ ) cume="$curline"
carry="${curline:0:-2}";;
* ) build "$curline";;
esac
done
if [ -n "$carry" ]; then
build "$carry"
fi
exec 3<&-
fi
}
build () {
curline="$1"
if [ -n "$curline" ]; then
case $curline in
\#* ) if [ -n "${comments[${#lines[@]}]}" ]; then
comments[${#lines[@]}]+="${NEWLINE} $curline"
else
comments[${#lines[@]}]=" $curline"
fi;;
* )
label=$(echo "${comments[${#lines[@]}]}" | \
sed -n -e 's/.*:\([^: ]*\):.*/\1/p')
if [ -n "$label" ]; then
# XXX debug:
#echo $label
labels[${label}]="$curline"
fi
lines[${#lines[@]}]="$curline";;
esac
fi
}
if [ ! .frequents -ef ~/.frequents ]; then
frequents=.frequents
else
frequents=~/.frequents
fi
if [ "$(tail -c 1 $frequents)" != "$(echo -e '\n')" ]; then
echo "(NOTE: $frequents lacks a trailing newline)" 1>&2
fi
read_from $frequents
size=${#lines[@]}
if [ "$size" = 0 ]; then
echo "no entries"
exit
fi
which=""
if [ -n "$arg" ]; then
which="$arg"
else
echo
incr=0
for i in "${lines[@]}"; do
if [ -n "${comments[$incr]}" ]; then
echo "${comments[$incr]}"
fi
echo $((incr++)): $i
done
echo
echo -n "execute command from line number[empty input to cancel]: "
read which
fi
mode=""
case "$which" in
[0-9] | [0-9][0-9] | [0-9][0-9][0-9]) mode=number ;;
* ) mode=alpha;;
esac
if [ "x$mode" = "xnumber" ]; then
if [ -z "${lines[$which]}" ]; then
echo no match
exit 1
else
echo "$which: ${lines[$which]}"
eval "${lines[$which]}"
fi
else
if [ -z "$which" ]; then
echo no match
exit 1
elif [ -z "${labels[$which]}" ]; then
echo no match
exit 1
else
echo "$which: ${labels[$which]}"
eval "${labels[$which]}"
fi
fi