some 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #! /bin/bash
  2. # Script to print "some" lines of a file, like head or tail but, random start
  3. #
  4. # Usage: some [[-#] FILE]
  5. # Helper functions
  6. PROG=`basename "$0" | tr -d '\n'`
  7. function info() { echo ${PROG}\: info: "$@" 1>&2; }
  8. function warn() { echo ${PROG}\: warning: "$@" 1>&2; }
  9. function error() { echo ${PROG}\: error: "$@" 1>&2; }
  10. function debug() { [[ -v DEBUG ]] && echo ${PROG}\: debug: "$@" 1>&2 || true ; }
  11. function die() { echo ${PROG}\: fatal: "$@" 1>&2 && exit 1; }
  12. function someFunc {
  13. # Functon to print "some" lines of a file, like head or tail but, random start
  14. #
  15. # ARGS:
  16. #
  17. # $1 - "-#" or FILENAME if only one arg
  18. # $2 - FILENAME if present
  19. set -e; set -u; set -o pipefail # be safe out there
  20. HOW_MANY=10 # Number of lines to print. Default.
  21. FILE="/dev/stdin" # default
  22. SOMELOG=${HOME}/.somelog # log of queries in case you want to find that chunk again
  23. MAXLOG=10
  24. if [ "$#" -eq 0 ]; then
  25. :
  26. elif [ "$#" -eq 1 ]; then
  27. if [[ "$1" =~ -[0-9] ]]; then
  28. HOW_MANY=`echo "$1" | sed 's/^-//'`
  29. else
  30. FILE="$1"
  31. fi
  32. elif [ "$#" -eq 2 ]; then
  33. if [[ "$1" =~ -[0-9] ]]; then
  34. HOW_MANY=`echo "$1" | sed 's/^-//'`
  35. else
  36. echo "some: Usage: some [-# [FILE]]"
  37. return
  38. fi
  39. FILE="$2"
  40. fi
  41. # Count the lines to bound display
  42. LINES=`wc -l $FILE | sed -e 's/ .*//'`
  43. # pick a random starting line at least HOW_MANY back from the end
  44. FIRST=$((1 + RANDOM % (LINES - HOW_MANY + 1 )))
  45. FIRST=$((FIRST>LINES ? LINES : FIRST))
  46. LAST=$((FIRST + HOW_MANY - 1))
  47. LAST=$((LAST>LINES ? LINES : LAST))
  48. # display line numbers to stderr to allow re-extraction of randomly chosen lines
  49. echo some: lines $FIRST to $LAST \(of $LINES\) of $FILE |& tee /dev/stderr >> ${SOMELOG}
  50. # only keep MAXLOG lines of SOMELOG
  51. mv ${SOMELOG} ${SOMELOG}.$$ && tail -${MAXLOG} ${SOMELOG}.$$ > ${SOMELOG} && rm ${SOMELOG}.$$
  52. # Let's see some lines !
  53. awk "NR >= $FIRST && NR <= $LAST" $FILE
  54. }
  55. someFunc $*