tsvselect (2084B)
1 #!/bin/sh 2 # vim: set ft=bash: 3 # tsvselect - Select a line from a TSV file 4 # This program is licensed under the terms of GNU GPL v3 or (at your option) 5 # any later version. Copyright (C) 2023-2026 Страхиња Радић. 6 # See the file LICENSE for exact copyright and license details. 7 8 tab=$(printf "\t") 9 nl=' 10 ' 11 12 usage() 13 { 14 cat <<EOT 15 Usage: ${0##*/} tsvfile.tsv [rowno | colno text] 16 EOT 17 } 18 19 error() 20 { 21 printf "%s: %s\n" "${0##*/}" "$@" >&2 22 } 23 24 case $# in 25 2) inputfile=$1 26 lineno=$2 27 ;; 28 3) inputfile=$1 29 colno=$2 30 searchtext=$3 31 ;; 32 *) usage 33 exit 1 34 ;; 35 esac 36 37 # Exit silently without failing if the file doesn't exist. This enables tsvins 38 # to work on new files, not existing up to that point 39 [ ! -f "${inputfile}" ] && exit 40 41 [ -w "${inputfile}" ] || { error "\`${inputfile}' not writeable"; exit 1; } 42 numlines=$(awk 'END {print NR}' "${inputfile}") 43 command -v vipe >/dev/null 2>&1 || { error "vipe not found"; exit 1; } 44 45 # shellcheck disable=SC2086 46 if [ ! $lineno ]; then 47 lineno=$(cut -d"$tab" -f"${colno}" -- "${inputfile}" | 48 grep -n "${searchtext}" | sed 's/^\([0-9]\+\).*/\1/;1q') 49 # shellcheck disable=SC2086 50 [ ! $lineno ] && 51 { error "not found \`${searchtext}' in column ${colno}" 52 exit 1; } 53 fi 54 55 savelineno="${lineno}" 56 # shellcheck disable=SC2086 57 (while [ $lineno ]; do 58 case $(printf "%s\n" "${lineno}" | cut -c 1) in 59 [0-9]) ;; 60 *) error "argument not a number: \`${savelineno}'" 61 exit 1 62 ;; 63 esac 64 # shellcheck disable=SC2030 65 lineno=$(printf "%s\n" "${lineno}" | cut -c 2-) 66 done) || exit 1 67 68 # shellcheck disable=SC2031 69 if [ "${lineno}" -lt 1 ]; then 70 error "line number must be positive: \`${lineno}'" 71 exit 1 72 fi 73 74 if [ "${numlines}" -gt 0 ]; then 75 # shellcheck disable=SC1003 76 { sed 1q "${inputfile}" | 77 sed -e 's/^/# /' -e 's/'"$tab"'/'"$tab"'# /g' 78 # shellcheck disable=SC2031 79 if [ "${lineno}" -le "${numlines}" ]; then 80 head -n"${lineno}" -- "${inputfile}" | tail -n1 81 else 82 sed 1q "${inputfile}" | 83 sed -e 's/[^'"$tab"']*\('"$tab"'\)/\1/g' \ 84 -e 's/[^'"$tab"']*$//' 85 fi; } | 86 transpose - | sed -e 's/'"$tab"'/\'"$nl"'/g' 87 fi