functions 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. _haz() {
  2. command -v "$1" > /dev/null 2>&1
  3. }
  4. human() {
  5. local number=${1:-0}
  6. local decimal
  7. local sizeIdx=0
  8. local size=(Bytes {K,M,G,T,E,P,Y,Z}B)
  9. while ((number > 1000)); do
  10. decimal="$(printf ".%02d" $((number % 1000 * 100 / 1000)))"
  11. number=$((number / 1000))
  12. (( sizeIdx++ ))
  13. done
  14. printf "$number$decimal ${size[$sizeIdx]}\n"
  15. }
  16. spell() {
  17. local candidates oldifs word array_pos
  18. oldifs="$IFS"
  19. IFS=':'
  20. # Parse the apsell format and return a list of ":" separated words
  21. read -a candidates <<< "$(printf "%s\n" "$1" \
  22. | aspell -a \
  23. | awk -F':' '/^&/ {
  24. split($2, a, ",")
  25. result=""
  26. for (x in a) {
  27. gsub(/^[ \t]/, "", a[x])
  28. result = a[x] ":" result
  29. }
  30. gsub(/:$/, "", result)
  31. print result
  32. }')"
  33. # Reverse number and print the parsed bash array because the list comes
  34. # out of gawk backwards
  35. for item in "${candidates[@]}"; do
  36. printf '%s\n' "$item"
  37. done \
  38. | tac \
  39. | nl \
  40. | less -FirSX
  41. printf "[ $(tput setaf 2)?$(tput sgr0) ]\t%s" \
  42. 'Enter the choice (empty to cancel, 0 for input): '
  43. read index
  44. [[ -z "$index" ]] && return
  45. [[ "$index" == 0 ]] && word="$1"
  46. [[ -z "$word" ]] && {
  47. array_pos=$(( ${#candidates[@]} - index ))
  48. word="${candidates[$array_pos]}"
  49. }
  50. [[ -n "$word" ]] && {
  51. printf "$word" | xsel -p
  52. printf "Copied '%s' to clipboard!\n" "$word"
  53. } || printf "[ $(tput setaf 1):($(tput sgr0) ] %s\n" 'No match found'
  54. IFS="$oldifs"
  55. }
  56. # Copy w/ progress
  57. cp_p () {
  58. rsync -WavP --human-readable --progress $1 $2
  59. }
  60. # All the dig info
  61. function digga() {
  62. dig +nocmd "$1" any +multiline +noall +answer
  63. }
  64. # Simple calculator
  65. function calc() {
  66. local result=""
  67. result="$(printf "scale=10;$*\n" | bc --mathlib | tr -d '\\\n')"
  68. # └─ default (when `--mathlib` is used) is 20
  69. #
  70. if [[ "$result" == *.* ]]; then
  71. # improve the output for decimal numbers
  72. printf "$result" |
  73. sed -e 's/^\./0./' `# add "0" for cases like ".5"` \
  74. -e 's/^-\./-0./' `# add "0" for cases like "-.5"`\
  75. -e 's/0*$//;s/\.$//' # remove trailing zeros
  76. else
  77. printf "$result"
  78. fi
  79. printf "\n"
  80. }
  81. findalias () {
  82. unset file
  83. grep -HiERn "alias ${1}=.*" /etc/bashrc ~/.${MYSHELL}rc $HOME/.exports $HOME/.aliases $HOME/.functions $HOME/.extra
  84. }
  85. ### User functions ###
  86. extract () {
  87. if [ -f $1 ] ; then
  88. case $1 in
  89. *.tar.bz2) tar xjf $1 ;;
  90. *.tar.gz) tar xzf $1 ;;
  91. *.bz2) bunzip2 $1 ;;
  92. *.rar) rar x $1 ;;
  93. *.gz) gunzip $1 ;;
  94. *.tar) tar xf $1 ;;
  95. *.tbz2) tar xjf $1 ;;
  96. *.tgz) tar xzf $1 ;;
  97. *.zip) unzip $1 ;;
  98. *.Z) uncompress $1 ;;
  99. *.7z) 7z x $1 ;;
  100. *) echo "'$1' cannot be extracted via extract()" ;;
  101. esac
  102. else
  103. echo "'$1' is not a valid file"
  104. fi
  105. }
  106. g() {
  107. if [ $# -gt 0 ]; then
  108. git "$@"
  109. else
  110. git hist3
  111. fi
  112. }
  113. gco() {
  114. if [ $# -gt 0 ]; then
  115. git checkout "$@"
  116. else
  117. git branch
  118. fi
  119. }
  120. # Start an HTTP server from a directory, optionally specifying the port
  121. function server() {
  122. local port="${1:-8000}"
  123. sleep 1 && open "http://localhost:${port}/" &
  124. # Set the default Content-Type to `text/plain` instead of `application/octet-stream`
  125. # And serve everything as UTF-8 (although not technically correct, this doesn’t break anything for binary files)
  126. python -c $'import SimpleHTTPServer;\nmap = SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map;\nmap[""] = "text/plain";\nfor key, value in map.items():\n\tmap[key] = value + ";charset=UTF-8";\nSimpleHTTPServer.test();' "$port"
  127. }
  128. # Display image with tput
  129. function image() {
  130. convert $1 -resize 40 txt:-|sed -E 's/://;s/\( ? ?//;s/, ? ?/,/g;s/\)//;s/([0-9]+,[0-9]+,[0-9]+),[0-9]+/\1/g;s/255/254/g;/mage/d'|awk '{print $1,$2}'|sed -E 's/^0,[0-9]+ /print "echo;tput setaf "\;/;s/^[0-9]+,[0-9]+ /print "tput setaf ";/;s/(.+),(.+),(.+)/\1\/42.5*36+\2\/42.5*6+\3\/42.5+16/'|bc|sed 's/$/;echo -n " ";/'|tr '\n' ' '|sed 's/^/tput rev;/;s/; /;/g;s/$/tput sgr0;echo/'|bash
  131. }
  132. # Pengwynn gxpr https://raw.github.com/pengwynn/dotfiles/ba9efd3d3073314d52d891e9f32b2ca6d26d5d3a/bin/gxpr
  133. # Usage: gxpr <expression>
  134. # Like expr(1), but uses Google's calculator to evaluate <expression>.
  135. #
  136. # Math examples:
  137. # $ gxpr '1 + 1'
  138. # 2
  139. #
  140. # $ gxpr 2 ^ 16
  141. # 65536
  142. #
  143. # $ gxpr '(2 ^ 1) + (2 ^ 2) + (2 ^ 3) + (2 ^ 5)'
  144. # 46
  145. #
  146. # $ gxpr '5*9+(sqrt 10)^3='
  147. # 76.6227766
  148. #
  149. # Conversion examples:
  150. # $ gxpr 1GB in KB
  151. # 1048576 kilobytes
  152. #
  153. # $ gxpr 10 megabits in megabytes
  154. # 1.25 megabytes
  155. #
  156. # $ gxpr 2 miles in inches
  157. # 126720 inches
  158. function gxpr() {
  159. local CURL_PATH=$(which curl)
  160. local CURL="$CURL_PATH -s --header 'User-Agent:gxpr/1.0'"
  161. local SEARCH="http://www.google.com/search"
  162. local EXPR=$(echo "$@" | sed -e 's/+/%2B/g' -e 's/ /+/g')
  163. local PAGE=$(curl -s --header 'User-Agent:gxpr/1.0' "http://www.google.com/search?q=$EXPR")
  164. res=$(
  165. echo $PAGE |
  166. perl -ne '/<h2 class="r".*?>(.*)<\/h2>/ and print $1' |
  167. perl -ne '/= (.*)/ and print $1' |
  168. perl -pe 's/[^\x00-\x7F]//g'
  169. )
  170. # if we don't have a result, assume it's an invalid expression
  171. test -z "$res" && {
  172. echo "invalid expression:" "$@" 1>&2
  173. }
  174. echo "$res"
  175. }
  176. function psgrep() {
  177. ps axuf | grep -v grep | grep "$@" -i --color=auto
  178. }
  179. function fname() {
  180. find . -iname "*$@*"
  181. }
  182. function take() {
  183. mkdir $1 && cd $1
  184. }
  185. speedread () {
  186. (while read line; do
  187. for word in $line; do
  188. clear
  189. for i in $(seq 0 $(( LINES / 2 - 4 ))); do
  190. printf "\n"
  191. done
  192. figlet -c -w $COLUMNS $word
  193. sleep 0.2
  194. done
  195. done
  196. printf "\n") < "$1"
  197. }
  198. # http://notary.icsi.berkeley.edu/
  199. bdns() {
  200. sum=$(openssl s_client -connect ${1}:443 < /dev/null 2>/dev/null | openssl x509 -outform DER | openssl sha1 | awk '{print $2}')
  201. echo "$sum"
  202. dig +short txt ${sum}.notary.icsi.berkeley.edu
  203. }
  204. # http://jeroenjanssens.com/2013/08/16/quickly-navigate-your-filesystem-from-the-command-line.html
  205. jump () {
  206. cd -P "$MARKPATH/$1" 2>/dev/null || echo "No such mark: $1"
  207. }
  208. mark() {
  209. local markdirname="$(dirname $1)"
  210. if [[ "$markdirname" != "." ]]; then
  211. mkdir -p "$MARKPATH/${markdirname}"
  212. else
  213. mkdir -p "$MARKPATH"
  214. fi
  215. ln -s "$(pwd)" "$MARKPATH/$1"
  216. }
  217. unmark() {
  218. rm -i "$MARKPATH/$1"
  219. }
  220. marks() {
  221. ls -l "$MARKPATH" | sed 's/ / /g' | cut -d' ' -f9- | sed 's/ -/\t-/g' && echo
  222. }
  223. # autocomplete marks
  224. if _haz compctl; then
  225. _completemarks() {
  226. reply=($(ls $MARKPATH))
  227. }
  228. compctl -K _completemarks jump
  229. compctl -K _completemarks unmark
  230. fi
  231. if _haz complete; then
  232. _completemarks() {
  233. local curw=${COMP_WORDS[COMP_CWORD]}
  234. local wordlist=$(find $MARKPATH -type l -printf "%f\n")
  235. COMPREPLY=($(compgen -W '${wordlist[@]}' -- "$curw"))
  236. return 0
  237. }
  238. complete -F _completemarks jump unmark
  239. fi
  240. # note () {
  241. # if (( $# == 0 )); then
  242. # local fn="${_N_PATH:=$HOME/.notes}"
  243. # else
  244. # local fn="${_N_PATH:=$HOME/.notes}/${@}.note"
  245. # fi
  246. #
  247. # mkdir -p "${_N_PATH:=$HOME/.notes}"; vim --cmd "autocmd VimLeave *.note :! bash -ci \"gist %\" &> /dev/null" -- "$fn";
  248. # }
  249. gist () {
  250. if [[ "$1" == *.note ]]; then
  251. local _prename="$(basename $1)"
  252. local name="[NOTE] ${_prename%.*}.md"
  253. else
  254. local _prename="$(basename $1)"
  255. local name="${_prename}"
  256. fi
  257. local filename="/tmp/gist-$(date +%s)";
  258. echo "{\"description\":\"$(basename ${1})\",\"public\":\"false\",\"files\":{\"${name}\":{\"content\":\"" > "$filename"
  259. cat "$1" | tr '"' "'" | sed ':a;N;$!ba;s/\n/\\n/g' >> "$filename"
  260. echo "\"}}" >> "$filename"
  261. curl -H "Authorization: token $GITHUB_TOKEN" -X POST --data @"$filename" https://api.github.com/gists
  262. \rm -- "$filename"
  263. }
  264. # Conversion
  265. ascii2hex () {
  266. printf "$@" | xxd -p -c1 -u
  267. }
  268. hex2bin () {
  269. hex=$(echo "$1" | tr '[:lower:]' '[:upper:]')
  270. echo "ibase=16; obase=2; $hex" | bc | awk '{printf "%08s\n", $0}'
  271. }
  272. bin2hex () {
  273. echo "ibase=2; obase=16; $1" | bc
  274. }
  275. ascii2bin () {
  276. while read hex; do
  277. echo "ibase=16; obase=2; $hex" | bc | awk '{printf "%08s\n", $0}'
  278. done < <(printf "$@" | xxd -p -c1 -u)
  279. }
  280. # Decode \x{ABCD}-style Unicode escape sequences
  281. function unidecode() {
  282. perl -e "binmode(STDOUT, ':utf8'); print \"$@\"";
  283. # print a newline unless we’re piping the output to another program
  284. if [ -t 1 ]; then
  285. echo ""; # newline
  286. fi;
  287. }
  288. # Get a character’s Unicode code point
  289. function codepoint() {
  290. perl -e "use utf8; print sprintf('U+%04X', ord(\"$@\"))";
  291. # print a newline unless we’re piping the output to another program
  292. if [ -t 1 ]; then
  293. echo ""; # newline
  294. fi;
  295. }
  296. # Show all the names (CNs and SANs) listed in the SSL certificate
  297. # for a given domain
  298. function getcertnames() {
  299. if [ -z "${1}" ]; then
  300. echo "ERROR: No domain specified.";
  301. return 1;
  302. fi;
  303. local domain="${1}";
  304. echo "Testing ${domain}…";
  305. echo ""; # newline
  306. local tmp=$(echo -e "GET / HTTP/1.0\nEOT" \
  307. | openssl s_client -connect "${domain}:443" 2>&1);
  308. if [[ "${tmp}" = *"-----BEGIN CERTIFICATE-----"* ]]; then
  309. local certText=$(echo "${tmp}" \
  310. | openssl x509 -text -certopt "no_header, no_serial, no_version, \
  311. no_signame, no_validity, no_issuer, no_pubkey, no_sigdump, no_aux");
  312. echo "Common Name:";
  313. echo ""; # newline
  314. echo "${certText}" | grep "Subject:" | sed -e "s/^.*CN=//";
  315. echo ""; # newline
  316. echo "Subject Alternative Name(s):";
  317. echo ""; # newline
  318. echo "${certText}" | grep -A 1 "Subject Alternative Name:" \
  319. | sed -e "2s/DNS://g" -e "s/ //g" | tr "," "\n" | tail -n +2;
  320. return 0;
  321. else
  322. echo "ERROR: Certificate not found.";
  323. return 1;
  324. fi;
  325. }
  326. read_mime() {
  327. local file="$1"
  328. xdg-mime query filetype "$file" 2>/dev/null | cut -d ';' -f 1
  329. }
  330. wiki() {
  331. local keyword=$(printf "$1" | perl -pe's/([^-_.~A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg')
  332. dig +short txt "$keyword.wp.dg.cx"
  333. }
  334. tc () {
  335. local _start_time=$(date +%s)
  336. export TERM="screen-256color"
  337. if command -v mux; then
  338. mux start "$1"
  339. elif command -v tmux; then
  340. tmux new -s "$1"
  341. else
  342. unset _start_time
  343. printf "$(tput setaf 1)[ERR]$(tput sgr0) Tmux not found\n"
  344. fi
  345. local _end_time=$(date +%s)
  346. local _total_time=$(( _end_time - _start_time ));
  347. if ((_end_time == _start_time || _start_time == 0)); then
  348. _total_time=0
  349. fi
  350. (( $_total_time < 5 )) && return
  351. local days=$(( $_total_time / 60 / 60 / 24 ))
  352. local hours=$(( $_total_time / 60 / 60 % 24 ))
  353. local minutes=$(( $_total_time / 60 % 60 ))
  354. local seconds=$(( $_total_time % 60 ))
  355. echo "$(date -R) - ${days}d ${hours}h ${minutes}m ${seconds}s" >> "$HOME/.work_log"
  356. unset days hours minutes seconds _total_time _start_time _end_time
  357. }
  358. # ZShell Completions
  359. if _haz compctl; then
  360. _completenotes() {
  361. reply=($(ls "${_N_PATH:=$HOME/.notes}"))
  362. }
  363. compctl -K _completenotes n
  364. # Bash Completions
  365. elif _haz complete; then
  366. _completenotes() {
  367. local cur=${COMP_WORDS[COMP_CWORD]}
  368. local wordlist=$(find ${_N_PATH:=$HOME/.notes} -type f -name '*.note' -printf "%f\n")
  369. COMPREPLY=($(compgen -W '${wordlist[@]}' -- "$cur"))
  370. return 0
  371. }
  372. complete -F _completenotes n
  373. fi
  374. # find all files under current dir with no eol on last line
  375. findnoeol() {
  376. pcregrep -LMr '\n$' . | grep -v .git | less -FirSX
  377. }
  378. h() {
  379. grep -i $1 ~/.muh_history
  380. }
  381. # List files provided by debian packages
  382. # http://superuser.com/a/904419
  383. deb-files() {
  384. local os=$(lsb_release -si | sed -e 's Ubuntu http://packages.ubuntu.com/ ' -e 's Debian https://packages.debian.org/ ')
  385. local release=$(lsb_release -sc)
  386. local package=$1
  387. local list=$(curl -q -s "${os}/${release}/all/${package}/filelist")
  388. echo "$list" | sed -n -e '/<pre>/,/<\/pre>/p' | sed -e 's/<[^>]\+>//g' -e '/^$/d';
  389. }
  390. deb-grep() {
  391. local package=$1
  392. local grep_args=$2
  393. for file in $(deb-files "$package"); do
  394. if dpkg-query -W "$package" &> /dev/null; then
  395. found=$(strings "$file" | grep $grep_args)
  396. if [ -n "$found" ]; then
  397. printf '\n\n[ %s ]\n' "$file"
  398. printf "$found"
  399. fi
  400. else
  401. echo "Package $package not installed"
  402. fi
  403. done
  404. }
  405. thousands() {
  406. awk '{ printf("%'"'"'d\n",$1); }'
  407. }