You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
3.2 KiB

  1. #!/bin/sh
  2. set -eu
  3. # variables
  4. #
  5. FROM=
  6. UNTIL=
  7. SED_ARGS=
  8. GREP_ARGS=
  9. GREPV_ARGS=
  10. # bin helpers
  11. #
  12. if STDBUF=$(which stdbuf); then
  13. STDBUF="$STDBUF -i0 -o0"
  14. fi
  15. PERL=$(which perl || true)
  16. if [ -n "$(sed 2>&1 | grep -- -u,)" ]; then
  17. SED="sed -u"
  18. else
  19. SED="${STDBUF:+$STDBUF }sed"
  20. fi
  21. GREP="${STDBUF:+$STDBUF }grep"
  22. # Colours
  23. #
  24. NORMAL="$(printf '\x1b[39;49m')"
  25. COLOUR="$NORMAL"
  26. RED="$(printf '\x1b[31m')"
  27. GREEN="$(printf '\x1b[32m')"
  28. YELLOW="$(printf '\x1b[33m')"
  29. BLUE="$(printf '\x1b[34m')"
  30. MAGENTA="$(printf '\x1b[35m')"
  31. CYAN="$(printf '\x1b[36m')"
  32. # shell helpers
  33. #
  34. die() {
  35. local arg0="$(basename "$0")"
  36. if [ $# -eq 0 ]; then
  37. sed -e "s!^!$arg0 :"
  38. else
  39. echo "$arg0: $@"
  40. fi >&2
  41. exit 1
  42. }
  43. cat <<EOT >&2
  44. # $PWD
  45. # $0 $*
  46. EOT
  47. # arguments
  48. #
  49. while [ $# -gt 0 ]; do
  50. case "${1:-}" in
  51. -f)
  52. # prefilter from
  53. FROM="$2"
  54. shift
  55. ;;
  56. -u)
  57. # prefilter until
  58. UNTIL="$2"
  59. shift
  60. ;;
  61. -e)
  62. # highlight pattern
  63. #
  64. if [ "$COLOUR" = "$RED" ]; then
  65. COLOUR="$GREEN"
  66. elif [ "$COLOUR" = "$GREEN" ]; then
  67. COLOUR="$MAGENTA"
  68. elif [ "$COLOUR" = "$MAGENTA" ]; then
  69. COLOUR="$YELLOW"
  70. elif [ "$COLOUR" = "$YELLOW" ]; then
  71. COLOUR="$CYAN"
  72. elif [ "$COLOUR" = "$CYAN" ]; then
  73. COLOUR="$BLUE"
  74. else
  75. COLOUR="$RED"
  76. fi
  77. case "$2" in
  78. "^"*"$") PATTERN="$2" ;;
  79. "^"*) PATTERN="$2.*" ;;
  80. *"$") PATTERN=".*$2" ;;
  81. *) PATTERN=".*$2.*"
  82. esac
  83. SED_ARGS="${SED_ARGS:+$SED_ARGS }-e 's!$PATTERN!$COLOUR\0$NORMAL!g'"
  84. shift
  85. ;;
  86. # simple grep options with arguments
  87. -C|-A|-B)
  88. GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1 $2"
  89. shift
  90. ;;
  91. # grep options with merged arguments
  92. -C*|-A*|-B*)
  93. GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }'$1'"
  94. ;;
  95. # complex grep options with arguments
  96. -E)
  97. GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1 '$2'"
  98. shift
  99. ;;
  100. # -g is `grep -e`
  101. -g)
  102. GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }-e '$2'"
  103. shift
  104. ;;
  105. # -v is `grep -v e`
  106. -v)
  107. GREPV_ARGS="${GREPV_ARGS:+$GREPV_ARGS }-e '$2'"
  108. shift
  109. ;;
  110. # simple grep options without arguments
  111. -i)
  112. GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1"
  113. ;;
  114. --) shift
  115. break
  116. ;;
  117. # any other option
  118. -*)
  119. die "$1 unsupported"
  120. ;;
  121. # straight arguments
  122. *)
  123. break
  124. ;;
  125. esac
  126. shift
  127. done
  128. export LC_ALL=C
  129. #
  130. # compose pipeline
  131. #
  132. PIPELINE=
  133. # GREP -v FILTER
  134. if [ -n "${GREPV_ARGS:-}" ]; then
  135. PIPELINE="${PIPELINE:+$PIPELINE | }$GREP -a -v $GREPV_ARGS"
  136. fi
  137. # FROM/UNTIL FILTER
  138. if [ -z "${FROM:-}${UNTIL:-}" ]; then
  139. :
  140. elif [ -x "$PERL" ]; then
  141. prg=
  142. if [ -n "$FROM" ]; then
  143. prg="print if \$print; \$print ||= /$FROM/;"
  144. else
  145. prg="print;"
  146. fi
  147. [ -z "$UNTIL" ] || prg="last if /$UNTIL/; $prg"
  148. PIPELINE="${PIPELINE:+$PIPELINE | }$PERL -lne '$prg'"
  149. else
  150. PIPELINE="${PIPELINE:+$PIPELINE | }$SED"
  151. [ -z "${FROM:-}" ] || PIPELINE="$PIPELINE -e '0,/$FROM/d'"
  152. [ -z "${UNTIL:-}" ] || PIPELINE="$PIPELINE -e '/$UNTIL/,\$d'"
  153. # no grep? combine both sed calls
  154. if [ -z "${GREP_ARGS:-}" -a -n "${SED_ARGS:-}" ]; then
  155. PIPELINE="$PIPELINE $SED_ARGS"
  156. SED_ARGS=
  157. fi
  158. fi
  159. # GREP FILTER
  160. if [ -n "${GREP_ARGS:-}" ]; then
  161. PIPELINE="${PIPELINE:+$PIPELINE | }$GREP -a $GREP_ARGS"
  162. fi
  163. # HIGHLIGHT
  164. if [ -n "${SED_ARGS:-}" ]; then
  165. PIPELINE="${PIPELINE:+$PIPELINE | }$SED $SED_ARGS"
  166. fi
  167. #and run
  168. if [ $# -eq 0 ]; then
  169. eval "${PIPELINE:-cat}"
  170. elif [ -n "$PIPELINE" ]; then
  171. "$@" | $PIPELINE
  172. else
  173. "$@"
  174. fi