aboutsummaryrefslogtreecommitdiffstats
path: root/examples/scripts.v2/pages
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scripts.v2/pages')
-rw-r--r--examples/scripts.v2/pages187
1 files changed, 187 insertions, 0 deletions
diff --git a/examples/scripts.v2/pages b/examples/scripts.v2/pages
new file mode 100644
index 0000000..66ebc5f
--- /dev/null
+++ b/examples/scripts.v2/pages
@@ -0,0 +1,187 @@
+#! /bin/bash
+#
+# original from:
+# @(#) pages.sh 1.0 92/09/26
+# 92/09/05 John H. DuBois III (jhdiii@armory.com)
+# 92/09/26 Added help
+#
+# conversion to bash v2 syntax by Chet Ramey
+
+Usage="$0 [-h] [-n lines/page] page-ranges [file ...]"
+
+usage()
+{
+ echo "$Usage" 1>&2
+}
+
+phelp()
+{
+echo "$0: print selected pages.
+Usage: $Usage
+
+If no file names are given, the standard input is read.
+
+The input is grouped into pages and a selected subset of them is printed.
+Formfeeds are acted on correctly.
+
+If the output device does automatic line wrap, lines that longer than
+the width of the output device will result in incorrect output.
+The first non-option argument is a list of pages to print.
+
+Pages are given as a list of ranges separated by commas.
+A range is either one number, two numbers separted by a dash,
+or one number followed by a dash. A range consisting of one
+number followed by a dash extends to the end of the document.
+
+Options:
+-n sets the number of lines per page to n. The default is 66."
+}
+
+while getopts "n:h" opt; do
+ case "$opt" in
+ n) LinesPerPage=$OPTARG;;
+ h) phelp; exit 0;;
+ *) usage; exit 2;;
+ esac
+done
+
+shift $(($OPTIND - 1))
+
+if [ $# -eq 0 ]; then
+ echo $0: no page ranges given. 1>&2
+ usage
+ exit 1
+fi
+
+PageList=$1
+shift
+
+gawk "
+BEGIN {
+ PageList = \"$PageList\"; LinesPerPage = \"$LinesPerPage\""'
+ if (LinesPerPage == "")
+ LinesPerPage = 66
+ else
+ if (LinesPerPage !~ "[1-9][0-9]*")
+ ErrExit("Bad value for lines per page: " LinesPerPage)
+ LinesPerPage += 0
+ NumRanges = split(PageList,Ranges,",")
+ for (i = 1; i <= NumRanges; i++) {
+ if ((StartRange = EndRange = Ranges[i]) !~ "^[0-9]+(-([0-9]+)?)?$")
+ ErrExit("Bad range \"" StartRange "\"")
+ sub("-.*","",StartRange)
+ sub(".*-","",EndRange)
+ if (EndRange == "")
+ EndRange = 2 ^ 30
+ # Force StartRange and EndRange to be numeric values
+ if ((StartRange += 0) == 0 || (EndRange += 0) == 0)
+ ErrExit("Invalid page number \"0\" in range " Ranges[i])
+ if (StartRange > EndRange)
+ ErrExit("Start page comes after end page in range " Ranges[i])
+ TmpRangeStarts[i] = StartRange
+ TmpRangeEnds[i] = EndRange
+ }
+
+ # Sort ranges
+ qsort(TmpRangeStarts,k)
+ RangeEnds[0] = 0
+ for (i = 1; i <= NumRanges; i++) {
+ RangeEnds[i] = TmpRangeEnds[k[i]]
+ if ((RangeStarts[i] = TmpRangeStarts[k[i]]) <= RangeEnds[i - 1])
+ ErrExit("Overlapping ranges: " Ranges[k[i]] "," Ranges[k[i - 1]])
+ }
+
+ RangeNum = LineNum = PageNum = 1
+ InRange = In(PageNum,RangeStarts[RangeNum],RangeEnds[RangeNum])
+ FS = "\014"
+}
+
+{
+ if (LineNum > LinesPerPage)
+ NewPage()
+ if (InRange)
+ printf "%s",$1
+ # Deal with formfeeds
+ for (i = 2; i <= NF; i++) {
+ if (InRange)
+ printf "\014"
+ NewPage()
+ if (InRange)
+ printf "%s",$i
+ }
+ if (InRange)
+ print ""
+ LineNum++
+}
+
+function NewPage() {
+ PageNum++
+ LineNum = 1
+ # At the start of each page, check whether we are in a print range
+ WereInRange = InRange
+ InRange = In(PageNum,RangeStarts[RangeNum],RangeEnds[RangeNum])
+ # If last page was in range and we no longer are, move to next range
+ if (WereInRange && !InRange && ++RangeNum > NumRanges)
+ exit
+}
+
+function In(a,Min,Max) {
+ return (Min <= a && a <= Max)
+}
+
+function ErrExit(S) {
+ print S > "/dev/stderr"
+ Err = 1
+ exit 1
+}
+
+# Arr is an array of values with arbitrary indices.
+# Array k is returned with numeric indices 1..n.
+# The values in k are the indices of array arr,
+# ordered so that if array arr is stepped through
+# in the order arr[k[1]] .. arr[k[n]], it will be stepped
+# through in order of the values of its elements.
+# The return value is the number of elements in the array (n).
+function qsort(arr,k, ArrInd,end) {
+ end = 0
+ for (ArrInd in arr)
+ k[++end] = ArrInd;
+ qsortseg(arr,k,1,end);
+ return end
+}
+
+function qsortseg(arr,k,start,end, left,right,sepval,tmp,tmpe,tmps) {
+ # handle two-element case explicitely for a tiny speedup
+ if ((end - start) == 1) {
+ if (arr[tmps = k[start]] > arr[tmpe = k[end]]) {
+ k[start] = tmpe
+ k[end] = tmps
+ }
+ return
+ }
+ left = start;
+ right = end;
+ sepval = arr[k[int((left + right) / 2)]]
+ # Make every element <= sepval be to the left of every element > sepval
+ while (left < right) {
+ while (arr[k[left]] < sepval)
+ left++
+ while (arr[k[right]] > sepval)
+ right--
+ if (left < right) {
+ tmp = k[left]
+ k[left++] = k[right]
+ k[right--] = tmp
+ }
+ }
+ if (left == right)
+ if (arr[k[left]] < sepval)
+ left++
+ else
+ right--
+ if (start < right)
+ qsortseg(arr,k,start,right)
+ if (left < end)
+ qsortseg(arr,k,left,end)
+}
+' "$@"