File: ass.sh 1 #!/bin/sh 2 3 # The MIT License (MIT) 4 # 5 # Copyright © 2024 pacman64 6 # 7 # Permission is hereby granted, free of charge, to any person obtaining a copy 8 # of this software and associated documentation files (the “Software”), to deal 9 # in the Software without restriction, including without limitation the rights 10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 # copies of the Software, and to permit persons to whom the Software is 12 # furnished to do so, subject to the following conditions: 13 # 14 # The above copyright notice and this permission notice shall be included in 15 # all copies or substantial portions of the Software. 16 # 17 # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 # SOFTWARE. 24 25 26 # ass 27 # Arrogant Shell Shortcuts: 1-letter commands for your shell 28 # 29 # This is a collection of arguably useful shell functions and shortcuts: 30 # some of these can be real time/effort savers, letting you concentrate 31 # on getting things done. 32 # 33 # You're supposed to `source` this script, so its definitions stay for 34 # your whole shell session: for that, you can run `source ass` or 35 # `. ass` (no quotes either way), either directly or at shell startup. 36 # 37 # These shell functions rely on tools which are almost always available. 38 # 39 # 40 # Full list of funcs/commands added, with the memo-word each 1-letter name 41 # stands for 42 # 43 # a awk run `awk` 44 # b blow blow/expand tabs into spaces, using the tabstop given, or 4 45 # c cat run `cat`, which is useful, despite claims to the contrary 46 # d date run `date` 47 # e each run command using Each stdin line as a stdin-redirected file 48 # f files show all Files in a folder, digging recursively 49 # g grep run `grep` in extended mode 50 # h help show help messages for the command given 51 # i index index/number all lines, starting from 0 52 # j join join lines with tabs, optionally as n-item lines 53 # l less run `less`, enabling line numbers, scrolling, and ANSI styles 54 # m match case-sensitively match the extended-mode regex given 55 # n number number all lines, starting from 1 56 # o output unify output, by merging stderr into stdout 57 # p plain ignore ANSI terminal styling, resulting in proper plain-text 58 # q quiet ignore stderr 59 # r reflow reflow text/prose 60 # s sed run `sed` in extended mode 61 # t trim trim trailing spaces and carriage-returns 62 # u unixify ensure plain-text lines are unix-like 63 # v view run `less`, enabling scrolling and ANSI styles 64 # w web fetch a URI with `wget`, without saving the result to a file 65 # x xargs run `xargs`, using whole lines as extra arguments 66 # y year show a calendar for the current year, or for the year given 67 # z zip run `gzip` 68 69 70 # handle help options 71 case "$1" in 72 -h|--h|-help|--help) 73 # show help message, extracting the info-comment at the start 74 # of this file, and quit 75 awk '/^# +ass/, /^$/ { gsub(/^# ?/, ""); print }' "$0" 76 exit 0 77 ;; 78 esac 79 80 81 # Awk 82 a() { 83 awk "$@" 84 } 85 86 # Blow tabs into spaces, using the tabstop given, or 4 by default 87 b() { 88 local tabstop="${1:-4}" 89 shift 90 expand -t "${tabstop}" "$@" 91 } 92 93 # Cat 94 c() { 95 cat "$@" 96 } 97 98 # show the current Date and time, and the 3 `current` months 99 # d() { 100 # # debian linux has a different `cal` app which highlights the day 101 # if [ -e "/usr/bin/ncal" ]; then 102 # ncal -C -3 103 # else 104 # cal -3 105 # fi 106 # printf "%22s\x1b[32m%s\x1b[0m \x1b[34m%s\x1b[0m\n" " " \ 107 # "$(date +'%a %b %d')" "$(date +'%T')" 108 # } 109 110 # Date 111 d() { 112 date "$@" 113 } 114 115 # Find all files recursively in all folders given, or the current one 116 f() { 117 local arg 118 for arg in "${@:-.}"; do 119 find "${arg}" -type f 120 done 121 } 122 123 # Grep (extended-mode) 124 g() { 125 grep -E "$@" 126 } 127 128 # Help for the command given 129 h() { 130 man "${1}" || ("${1}" "${2:---help}" 2>&1 | less -KiCRS) 131 } 132 133 # Index/number all lines, starting from 0 134 i() { 135 awk '{ printf "%d\t%s\n", NR - 1, $0; fflush() }' "$@" 136 } 137 138 # Join lines with tabs, optionally as n-item lines 139 j() { 140 local n="${1:-0}" 141 shift 142 143 if [ "${n}" -le 0 ]; then 144 awk ' 145 NR > 1 { printf "\t" } 146 { printf "%s", $0 } 147 END { if (NR > 0) print "" }' "$@" 148 return "$?" 149 fi 150 151 awk -v n="${n}" ' 152 NR % n != 1 { printf "\t" } 153 { printf "%s", $0 } 154 NR % n == 0 { print "" } 155 END { if (NR % n != 0) print "" }' "$@" 156 } 157 158 # Kill processes, using all ID numbers given 159 # k() { 160 # kill -9 "$@" 161 # } 162 163 # run `less`, showing line numbers, among other settings 164 l() { 165 less -KNiCRS "$@" 166 } 167 168 # Match regex given, or non-empty lines by default 169 m() { 170 local regex="${1:-[^ *]\r?$}" 171 shift 172 grep -E "${regex}" "$@" 173 } 174 175 # Number lines, starting from 1 176 n() { 177 awk '{ printf "%d\t%s\n", NR, $0; fflush() }' "$@" 178 } 179 180 # unify Output, by merging stderr into stdout 181 o() { 182 "$@" 2>&1 183 } 184 185 # Plain text 186 p() { 187 awk ' 188 { 189 # ignore notifications (code 9) and hyperlinks (code 8) 190 gsub(/\x1b\](8|9);[^\x07]*\x07/, "") 191 # ignore cursor-movers and style-changers 192 gsub(/\x1b\[([0-9]*[A-HJKST]|[0-9;]*m)/, "") 193 194 print 195 fflush() 196 }' "$@" 197 } 198 199 # make stderr `Quiet`, by ignoring it 200 q() { 201 "$@" 2> /dev/null 202 } 203 204 # Reflow text/prose 205 r() { 206 local width="${1:-80}" 207 shift 208 awk ' 209 FNR == 1 { gsub(/^\xef\xbb\xbf/, "") } 210 FNR == 1 && NR > 1 { print "" } 211 1' "$@" | fold -s -w "${width}" | sed -E 's- *\r?$--' 212 } 213 214 # Sed (extended-mode) 215 s() { 216 sed -E "$@" 217 } 218 219 # Trim trailing spaces in lines, even trim trailing carriage-returns; also 220 # ignore leading UTF-8_BOMs (byte-order-marks) on each input's first line 221 t() { 222 awk 'FNR == 1 { gsub(/^\xef\xbb\xbf/, "") } 1' "$@" | 223 sed -E 's-^ +--; s- *\r?$--' 224 } 225 226 # Unixify lines, ignoring leading UTF-8_BOMs (byte-order-marks) on each 227 # input's first line, turning all end-of-line CRLF byte-pairs into single 228 # line-feeds, and ensuring each input's last line ends with a line-feed 229 u() { 230 awk 'FNR == 1 { gsub(/^\xef\xbb\xbf/, "") } 1' "$@" | sed -E 's-\r$--' 231 } 232 233 # View with `less` 234 v() { 235 less -KiCRS "$@" 236 } 237 238 # fetch a URI with `wget`, without saving the result to a file 239 w() { 240 # wget -O - "$@" 241 # curl --no-progress-meter "$@" 242 wget --no-verbose -O - "$@" 243 } 244 245 # run `xargs`, using whole lines as extra arguments 246 x() { 247 xargs -d '\n' "$@" 248 } 249 250 # show a calendar for the current year, or for the year given 251 y() { 252 # debian linux has a different `cal` app which highlights the day 253 if [ -e "/usr/bin/ncal" ]; then 254 ncal -C -y "$@" 255 else 256 cal -y "$@" 257 fi 258 } 259 260 # zip/unzip, using the `gzip` format 261 z() { 262 gzip "$@" 263 }