#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
# variables
|
|
#
|
|
FROM=
|
|
UNTIL=
|
|
|
|
SED_ARGS=
|
|
GREP_ARGS=
|
|
GREPV_ARGS=
|
|
|
|
# bin helpers
|
|
#
|
|
if STDBUF=$(which stdbuf); then
|
|
STDBUF="$STDBUF -i0 -o0"
|
|
fi
|
|
|
|
PERL=$(which perl || true)
|
|
if [ -n "$(sed 2>&1 | grep -- -u,)" ]; then
|
|
SED="sed -u"
|
|
else
|
|
SED="${STDBUF:+$STDBUF }sed"
|
|
fi
|
|
GREP="${STDBUF:+$STDBUF }grep"
|
|
|
|
# Colours
|
|
#
|
|
NORMAL="$(printf '\x1b[39;49m')"
|
|
COLOUR="$NORMAL"
|
|
|
|
RED="$(printf '\x1b[31m')"
|
|
GREEN="$(printf '\x1b[32m')"
|
|
YELLOW="$(printf '\x1b[33m')"
|
|
BLUE="$(printf '\x1b[34m')"
|
|
MAGENTA="$(printf '\x1b[35m')"
|
|
CYAN="$(printf '\x1b[36m')"
|
|
|
|
# shell helpers
|
|
#
|
|
die() {
|
|
local arg0="$(basename "$0")"
|
|
|
|
if [ $# -eq 0 ]; then
|
|
sed -e "s!^!$arg0 :"
|
|
else
|
|
echo "$arg0: $@"
|
|
fi >&2
|
|
exit 1
|
|
}
|
|
|
|
cat <<EOT >&2
|
|
# $PWD
|
|
# $0 $*
|
|
EOT
|
|
|
|
# arguments
|
|
#
|
|
while [ $# -gt 0 ]; do
|
|
|
|
case "${1:-}" in
|
|
-f)
|
|
# prefilter from
|
|
FROM="$2"
|
|
shift
|
|
;;
|
|
-u)
|
|
# prefilter until
|
|
UNTIL="$2"
|
|
shift
|
|
;;
|
|
|
|
-e)
|
|
# highlight pattern
|
|
#
|
|
if [ "$COLOUR" = "$RED" ]; then
|
|
COLOUR="$GREEN"
|
|
elif [ "$COLOUR" = "$GREEN" ]; then
|
|
COLOUR="$MAGENTA"
|
|
elif [ "$COLOUR" = "$MAGENTA" ]; then
|
|
COLOUR="$YELLOW"
|
|
elif [ "$COLOUR" = "$YELLOW" ]; then
|
|
COLOUR="$CYAN"
|
|
elif [ "$COLOUR" = "$CYAN" ]; then
|
|
COLOUR="$BLUE"
|
|
else
|
|
COLOUR="$RED"
|
|
fi
|
|
|
|
case "$2" in
|
|
"^"*"$") PATTERN="$2" ;;
|
|
"^"*) PATTERN="$2.*" ;;
|
|
*"$") PATTERN=".*$2" ;;
|
|
*) PATTERN=".*$2.*"
|
|
esac
|
|
|
|
SED_ARGS="${SED_ARGS:+$SED_ARGS }-e 's!$PATTERN!$COLOUR\0$NORMAL!g'"
|
|
shift
|
|
;;
|
|
|
|
# simple grep options with arguments
|
|
-C|-A|-B)
|
|
GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1 $2"
|
|
shift
|
|
;;
|
|
# grep options with merged arguments
|
|
-C*|-A*|-B*)
|
|
GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }'$1'"
|
|
;;
|
|
# complex grep options with arguments
|
|
-E)
|
|
GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1 '$2'"
|
|
shift
|
|
;;
|
|
# -g is `grep -e`
|
|
-g)
|
|
GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }-e '$2'"
|
|
shift
|
|
;;
|
|
# -v is `grep -v e`
|
|
-v)
|
|
GREPV_ARGS="${GREPV_ARGS:+$GREPV_ARGS }-e '$2'"
|
|
shift
|
|
;;
|
|
# simple grep options without arguments
|
|
-i)
|
|
GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1"
|
|
;;
|
|
|
|
--) shift
|
|
break
|
|
;;
|
|
# any other option
|
|
-*)
|
|
die "$1 unsupported"
|
|
;;
|
|
|
|
# straight arguments
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
export LC_ALL=C
|
|
|
|
#
|
|
# compose pipeline
|
|
#
|
|
|
|
PIPELINE=
|
|
|
|
# GREP -v FILTER
|
|
if [ -n "${GREPV_ARGS:-}" ]; then
|
|
PIPELINE="${PIPELINE:+$PIPELINE | }$GREP -a -v $GREPV_ARGS"
|
|
fi
|
|
|
|
# FROM/UNTIL FILTER
|
|
if [ -z "${FROM:-}${UNTIL:-}" ]; then
|
|
:
|
|
elif [ -x "$PERL" ]; then
|
|
prg=
|
|
|
|
if [ -n "$FROM" ]; then
|
|
prg="print if \$print; \$print ||= /$FROM/;"
|
|
else
|
|
prg="print;"
|
|
fi
|
|
|
|
[ -z "$UNTIL" ] || prg="last if /$UNTIL/; $prg"
|
|
|
|
PIPELINE="${PIPELINE:+$PIPELINE | }$PERL -lne '$prg'"
|
|
else
|
|
PIPELINE="${PIPELINE:+$PIPELINE | }$SED"
|
|
|
|
[ -z "${FROM:-}" ] || PIPELINE="$PIPELINE -e '0,/$FROM/d'"
|
|
[ -z "${UNTIL:-}" ] || PIPELINE="$PIPELINE -e '/$UNTIL/,\$d'"
|
|
|
|
# no grep? combine both sed calls
|
|
if [ -z "${GREP_ARGS:-}" -a -n "${SED_ARGS:-}" ]; then
|
|
PIPELINE="$PIPELINE $SED_ARGS"
|
|
SED_ARGS=
|
|
fi
|
|
fi
|
|
|
|
# GREP FILTER
|
|
if [ -n "${GREP_ARGS:-}" ]; then
|
|
PIPELINE="${PIPELINE:+$PIPELINE | }$GREP -a $GREP_ARGS"
|
|
fi
|
|
|
|
# HIGHLIGHT
|
|
if [ -n "${SED_ARGS:-}" ]; then
|
|
PIPELINE="${PIPELINE:+$PIPELINE | }$SED $SED_ARGS"
|
|
fi
|
|
|
|
#and run
|
|
if [ $# -eq 0 ]; then
|
|
eval "${PIPELINE:-cat}"
|
|
elif [ -n "$PIPELINE" ]; then
|
|
"$@" | $PIPELINE
|
|
else
|
|
"$@"
|
|
fi
|