чување 3befac7ff54777865c3ae524eb46e3ec68dbbe49
родитељ 93ab614f2086c800de00a04d1263affc20665d5d
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Thu, 14 Sep 2023 15:00:32 +0200
tsvfind: New command; ste.in: Add / and n commands
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | all.do | | | 4 | ++-- |
| M | install.do | | | 4 | ++-- |
| M | ste.1.in | | | 19 | +++++++++++++++++++ |
| M | ste.in | | | 209 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- |
| A | tsvfind | | | 79 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | tsvfind.1.in | | | 41 | +++++++++++++++++++++++++++++++++++++++++ |
| M | uninstall.do | | | 4 | ++-- |
измењених датотека: 7, додавања: 296(+), брисања: 64(-)
diff --git a/all.do b/all.do
@@ -1,2 +1,2 @@
-redo-ifchange ste ste.1.gz transpose.1.gz tsvedit.1.gz tsvdel.1.gz tsvins.1.gz \
- tsvmove.1.gz
+redo-ifchange ste ste.1.gz transpose.1.gz tsvdel.1.gz tsvedit.1.gz \
+ tsvfind.1.gz tsvins.1.gz tsvmove.1.gz
diff --git a/install.do b/install.do
@@ -11,9 +11,9 @@ MANDIR=$PREFIX/share/man/man1
# install -Dm 0644 "${docfile}" "${DOCDIR}/${docfile}"
#done
install -d $BINDIR $MANDIR
-for binfile in ste transpose tsvdel tsvins tsvedit tsvmove; do
+for binfile in ste transpose tsvdel tsvedit tsvfind tsvins tsvmove; do
install -m 0755 "${binfile}" "${BINDIR}/${binfile}"
done
-for manfile in ste transpose tsvdel tsvins tsvedit tsvmove; do
+for manfile in ste transpose tsvdel tsvedit tsvfind tsvins tsvmove; do
install -m 0644 "${manfile}.1.gz" "${MANDIR}/${manfile}.1.gz"
done
diff --git a/ste.1.in b/ste.1.in
@@ -35,6 +35,19 @@ Accepted commands are:
.
.Bl -tag -width "help | h" -offset indent
.
+.It Ic / Oo Ar colno Oc Ar text
+Search for
+.Ar text
+in all columns, continuing the search downwards as needed.
+If
+.Ar colno
+is given, limit the search to column number
+.Ar colno
+(1\-based).
+.Pp
+When the last row was reached without a match, the user will be prompted whether
+to continue the search from the first row.
+.
.It Ic =
Show current row.
.
@@ -115,6 +128,12 @@ If
.Ar num
is omitted, move the row pointer up.
.
+.It Ic n
+Find next occurence of previously searched text.
+If the argument
+.Ar colno
+was given in the last search, the search will reuse it.
+.
.It Ic print | Ic p
Print (redraw) the table.
.
diff --git a/ste.in b/ste.in
@@ -18,6 +18,7 @@ noansi=1
# Which flavors of TSV/CSV utilities to use
delprog=tsvdel
editprog=tsvedit
+findprog=tsvfind
insprog=tsvins
moveprog=tsvmove
tableprog=tsvtable
@@ -47,8 +48,10 @@ detectrows()
help()
{
case "$1" in
+ /) printf "/ text - Search for text\n"
+ printf "/ colno text - Search for text in column colno\n";;
=) printf "= - Show current row\n";;
- cols) printf "cols [amount] - Set screen width in columns\n"
+ cols) printf "cols amount - Set screen width in columns to amount\n"
printf " (0 = autodetect)\n"
printf "cols - Show the current screen width\n";;
delete|x)
@@ -56,7 +59,7 @@ help()
edit|e) printf "edit | e - Edit the current table row\n";;
exit|q) printf "exit | q - Exit %s\n" "$prog";;
G) printf "G - Set current row to last\n";;
- g) printf "g [num] - Set current table row to num (header = 0)\n"
+ g) printf "g num - Set current table row to num (header = 0)\n"
printf "g - Set current row to header row (0)\n";;
help|h) printf "help [command] | h [command] - Show help "
printf "(about a command)\n";;
@@ -66,24 +69,25 @@ help()
printf "insert + | i + - Add a row to the table after the "
printf "current line\n"
printf "insert | i - Add a row to the end of table\n";;
- J) printf "J [num] - Move the current row down num rows\n"
+ J) printf "J num - Move the current row down num rows\n"
printf "J - Move the current row down\n";;
- j) printf "j [num] - Move the current row pointer down num rows\n"
+ j) printf "j num - Move the current row pointer down num rows\n"
printf "j - Move the current row pointer down\n";;
- K) printf "K [num] - Move the current row up num rows\n"
+ K) printf "K num - Move the current row up num rows\n"
printf "K - Move the current row up\n";;
- k) printf "k [num] - Move the current row pointer up num rows\n"
+ k) printf "k num - Move the current row pointer up num rows\n"
printf "k - Move the current row pointer up\n";;
+ n) printf "n - Find next occurence of previously searched text\n";;
print|p)
printf "print | p - Print (redraw) the table\n";;
- rows) printf "rows [amount] - Set screen height in lines\n"
+ rows) printf "rows amount - Set screen height in lines\n"
printf " (0 = autodetect)\n"
printf "rows - Show the current screen height\n";;
- set) printf "set [[no]option] - Turn option on/off\n"
+ set) printf "set [no]option - Turn option on/off\n"
printf "set - Show option states\n";;
- "") printf "Commands: = cols delete e edit exit G g h help i "
- printf "insert J j K k p print q rows set x\n"
- printf "help [command] - Show help about a command\n";;
+ "") printf "Commands: / = cols delete e edit exit G g h help i "
+ printf "insert J j K k n p print q rows set x\n"
+ printf "help [command] - Show help (about a command)\n";;
*) error "Unknown command '%s'" "$args";;
esac
}
@@ -155,6 +159,7 @@ fi
continue=1
currow=0
firstrow=0
+nextcmd=''
oldcols=''
oldrows=''
redraw=1
@@ -223,9 +228,15 @@ while [ "$continue" -eq 1 ]; do
redraw=0
fi
- printf "%s[%dx%d+%d@%d/%d]> " \
- "${file##*/}" "$_cols" "$_rows" "$firstrow" "$currow" "$maxrows"
- read -r cmd
+ if [ -z "$nextcmd" ]; then
+ printf "%s[%dx%d+%d@%d/%d]> " \
+ "${file##*/}" "$_cols" "$_rows" "$firstrow" "$currow" \
+ "$maxrows"
+ IFS= read -r cmd
+ else
+ cmd="$nextcmd"
+ nextcmd=''
+ fi
IFS=' '
#shellcheck disable=SC2086
@@ -238,7 +249,60 @@ while [ "$continue" -eq 1 ]; do
args=''
fi
case "$cmd" in
- =) printf "Current row: %d\n" "$currow";;
+ /) set -- $args
+ searchcol=''
+ searchtext="$1"
+ if [ -n "$2" ]; then
+ searchcol="$1"
+ shift
+ searchtext="$*"
+ fi
+ if [ -z "$searchtext" ]; then
+ error "Argument required"
+ fi
+
+ if [ -z "$wrapped" ]; then
+ if [ -z "$searchcol" ]; then
+ newrow=$(${findprog} -s $((currow + 1)) \
+ "$file" "$searchtext")
+ else
+ newrow=$(${findprog} -s $((currow + 1)) \
+ "$file" "$searchcol" "$searchtext")
+ fi
+ else
+ if [ -z "$searchcol" ]; then
+ newrow=$(${findprog} "$file" "$searchtext")
+ else
+ newrow=$(${findprog} "$file" \
+ "$searchcol" "$searchtext")
+ fi
+ fi
+ wrapped=''
+
+ if [ -n "$newrow" ]; then
+ currow=$((newrow - 1))
+ redraw=1
+ else
+ printf "Text '%s' not found" "$searchtext"
+ if [ -n "$searchcol" ]; then
+ printf " in column %d" "$searchcol"
+ fi
+ printf ". Search from top [Y/n]? "
+ IFS= read -r yesno
+ case "$yesno" in
+ n|N) ;;
+ *) currow=0
+ wrapped=1
+ if [ -z "$searchcol" ]; then
+ nextcmd="/ $searchtext"
+ else
+ nextcmd="/ $searchcol $searchtext"
+ fi;;
+ esac
+ fi
+ ;;
+ =) printf "Current row: %d\n" "$currow"
+ ;;
cols) case "$args" in
"") if [ "$cols" -eq 0 ]; then
# shellcheck disable=SC2140
@@ -247,8 +311,9 @@ while [ "$continue" -eq 1 ]; do
else
printf "Current table width: %d\n" "$cols"
fi;;
- *) cols="$args"
+ [0-9]*) cols="$args"
redraw=1;;
+ *) error "Not a number: '%s'" "$args";;
esac
;;
delete|x)
@@ -273,12 +338,13 @@ while [ "$continue" -eq 1 ]; do
g) case "$args" in
"") currow=0
redraw=1;;
- *) if [ "$args" -ge 0 ] && [ "$args" -lt "$maxrows" ]; then
+ [0-9]*) if [ "$args" -ge 0 ] && [ "$args" -lt "$maxrows" ]; then
currow="$args"
redraw=1
else
error "Row out of range: '%s'" "$args"
fi;;
+ *) error "Not a number: '%s'" "$args";;
esac
;;
help|h|"")
@@ -297,50 +363,76 @@ while [ "$continue" -eq 1 ]; do
*) error "Invalid argument: '%s'" "$args";;
esac
;;
- J) torow=$((currow + 1))
- if [ -n "$args" ]; then
- torow=$((currow + args))
- fi
- if [ "$torow" -lt "$maxrows" ]; then
- ${moveprog} "$file" "$((currow+1))" "$((torow+1))"
- currow="$torow"
- redraw=1
- else
- error "Row out of range: '%s'" "$torow"
- fi
+ J) case "$args" in
+ ""|[0-9]*)
+ torow=$((currow + 1))
+ if [ -n "$args" ]; then
+ torow=$((currow + args))
+ fi
+ if [ "$torow" -lt "$maxrows" ]; then
+ ${moveprog} "$file" "$((currow+1))" "$((torow+1))"
+ currow="$torow"
+ redraw=1
+ else
+ error "Row out of range: '%s'" "$torow"
+ fi;;
+ *) error "Not a number: '%s'" "$args";;
+ esac
;;
- j) torow=$((currow + 1))
- if [ -n "$args" ]; then
- torow=$((currow + args))
- fi
- if [ "$torow" -lt "$maxrows" ]; then
- currow="$torow"
- redraw=1
- else
- error "Row out of range: '%s'" "$torow"
- fi
+ j) case "$args" in
+ ""|[0-9]*)
+ torow=$((currow + 1))
+ if [ -n "$args" ]; then
+ torow=$((currow + args))
+ fi
+ if [ "$torow" -lt "$maxrows" ]; then
+ currow="$torow"
+ redraw=1
+ else
+ error "Row out of range: '%s'" "$torow"
+ fi;;
+ *) error "Not a number: '%s'" "$args";;
+ esac
;;
- K) torow=$((currow - 1))
- if [ -n "$args" ]; then
- torow=$((currow - args))
- fi
- if [ "$torow" -ge 0 ]; then
- ${moveprog} "$file" "$((currow+1))" "$((torow+1))"
- currow="$torow"
- redraw=1
- else
- error "Row out of range: '%s'" "$torow"
- fi
+ K) case "$args" in
+ ""|[0-9*])
+ torow=$((currow - 1))
+ if [ -n "$args" ]; then
+ torow=$((currow - args))
+ fi
+ if [ "$torow" -ge 0 ]; then
+ ${moveprog} "$file" "$((currow+1))" "$((torow+1))"
+ currow="$torow"
+ redraw=1
+ else
+ error "Row out of range: '%s'" "$torow"
+ fi;;
+ *) error "Not a number: '%s'" "$args";;
+ esac
;;
- k) torow=$((currow - 1))
- if [ -n "$args" ]; then
- torow=$((currow - args))
- fi
- if [ "$torow" -ge 0 ]; then
- currow="$torow"
- redraw=1
+ k) case "$args" in
+ ""|[0-9]*)
+ torow=$((currow - 1))
+ if [ -n "$args" ]; then
+ torow=$((currow - args))
+ fi
+ if [ "$torow" -ge 0 ]; then
+ currow="$torow"
+ redraw=1
+ else
+ error "Row out of range: '%s'" "$torow"
+ fi;;
+ *) error "Not a number: '%s'" "$args";;
+ esac
+ ;;
+ n) if [ -z "$searchtext" ]; then
+ error "No previous search"
else
- error "Row out of range: '%s'" "$torow"
+ if [ -z "$searchcol" ]; then
+ nextcmd="/ $searchtext"
+ else
+ nextcmd="/ $searchcol $searchtext"
+ fi
fi
;;
print|p)
@@ -354,11 +446,12 @@ while [ "$continue" -eq 1 ]; do
else
printf "Current screen height: %d\n" "$rows"
fi;;
- *) rows="$args"
+ [0-9]*) rows="$args"
if [ "$rows" -ne 0 ] && [ "$rows" -lt 4 ]; then
rows=4
fi
redraw=1;;
+ *) error "Not a number: '%s'" "$args";;
esac
;;
set)
diff --git a/tsvfind b/tsvfind
@@ -0,0 +1,79 @@
+#!/bin/sh
+# vim: set ft=bash:
+# tsvfind - Search for text in a TSV file
+# This program is licensed under the terms of GNU GPL v3 or (at your option)
+# any later version. Copyright (C) 2023 Страхиња Радић.
+# See the file LICENSE for exact copyright and license details.
+
+tab=$(printf "\t")
+nl='
+'
+
+usage()
+{
+ cat <<EOT
+Usage: ${0##*/} [-s rowno] tsvfile.tsv [text | colno text]
+ -s Start at lineno
+EOT
+}
+
+error()
+{
+ printf "%s: %s\n" "${0##*/}" "$@" >&2
+}
+
+rowno=0
+
+OPTIND=1
+while getopts s: OPT >/dev/null 2>&1
+do
+ case $OPT in
+ s) rowno="$OPTARG"
+ ;;
+ ?) error "Unknown parameter '$1'"
+ usage >&2
+ exit 1
+ ;;
+ esac
+ OPTARG=
+done
+shift $((OPTIND-1))
+
+case $# in
+ 2) inputfile=$1
+ searchtext=$2
+ ;;
+ 3) inputfile=$1
+ colno=$2
+ searchtext=$3
+ ;;
+ *) usage
+ exit 1
+ ;;
+esac
+
+if [ -n "$colno" ]; then
+ awk 'BEGIN { FS = "\t"; RS = "\n" }
+ {
+ if (NR > '"$rowno"' && !found &&
+ $'"$colno"' ~ ".*'"$searchtext"'.*")
+ {
+ print NR
+ found = 1
+ exit 0
+ }
+ }
+ END { exit !found }' "$inputfile"
+else
+ awk 'BEGIN { FS = "\t"; RS = "\n" }
+ {
+ if (NR > '"$rowno"' && !found &&
+ $0 ~ ".*'"$searchtext"'.*")
+ {
+ print NR
+ found = 1
+ exit 0
+ }
+ }
+ END { exit !found }' "$inputfile"
+fi
diff --git a/tsvfind.1.in b/tsvfind.1.in
@@ -0,0 +1,41 @@
+.Dd %DATE%
+.Dt TSVFIND 1
+.Os
+.Sh NAME
+.Nm tsvfind
+.Nd Search for text in a TSV file
+.Sh SYNOPSIS
+.Nm
+.Op Fl s Ar rowno
+.Ar tsvfile.tsv
+.Op Ar text | Ar colno Ar text
+.Sh DESCRIPTION
+.
+.Nm
+searches the given TSV file for
+.Ar text
+and outputs the number (1\-based) of the row containing it on stdout if
+successful.
+If
+.Ar text
+is not found,
+.Nm
+sets return status to 1.
+.
+.Bl -tag -width ".Nm Ar rowno" -offset indent
+.
+.It Fl s Ar rowno
+Start from row number
+.Ar rowno
+(1\-based, not inclusive)
+.
+.It Ar text
+Text to search for
+.
+.It Ar colno
+Column number to limit the search to (1-based)
+.
+.El
+.Sh AUTHORS
+.An "Strahinya Radich" Aq contact@strahinja.org ,
+2023
diff --git a/uninstall.do b/uninstall.do
@@ -6,10 +6,10 @@ PREFIX=${PREFIX:-/usr/local}
BINDIR=$PREFIX/bin
#DOCDIR=$PREFIX/share/doc/ste
MANDIR=$PREFIX/share/man/man1
-for binfile in ste transpose tsvdel tsvins tsvedit tsvmove; do
+for binfile in ste transpose tsvdel tsvedit tsvfind tsvins tsvmove; do
rm -f "${BINDIR}/${binfile}"
done
-for manfile in ste transpose tsvdel tsvins tsvedit tsvmove; do
+for manfile in ste transpose tsvdel tsvedit tsvfind tsvins tsvmove; do
rm -f "${MANDIR}/${manfile}.1.gz"
done
#$(find $DOCDIR -type f)