Sunday, April 17, 2016

Recursive Factorial in bc!

alias factorial='_() { var=${1}; echo -en "scale=25;\ndefine f (x) {if (x <= 1) return (1);\nreturn (f(x-1) * x);}\nf(${var})\nquit" | bc;};_' 
Logic found on the bc man page. Note the newlines, bc is a bit finicky about newlines when dealing with functions on one-liners otherwise.

Tuesday, April 5, 2016

Printing key-value pairs from Bash Associative array

#!/bin/bash 

 ## Printing key-value pairs from a Bash associative array 
unset myarr && declare -A myarr 
let myarr["eightytwo"]+=8
let myarr["eightytwo"]+=74
myarr["thirteen"]+=1
myarr["thirteen"]+=3
let myarr["fiftythree"]+=48
let myarr["fiftythree"]+=5
for a in "${!myarr[@]}"; do echo "${a}: ${myarr["$a"]}"; done

Thursday, March 31, 2016

Bash Dynamic Loops -- Read file daemon

#!/bin/bash 

COND1="break"
COND2="sleep 1"
 ## Dynamically change the loop logic from continue reading, to read 
 ## all data and break. 
[[ -z "${1}" ]] && COND="${COND1}" || COND="${COND2}" 
while IFS= read -d $'\n' -r a || ${COND}; do 
 [[ -n "$a" ]] && echo "curl -s http://foo.bar/some.php?id=${a}"
done < id_list.txt

exit 0 

Monday, March 28, 2016

Replacing Nth Occurrence from End of Line via Sed

SEARCH="one" 
SEARCHNEG=$(sed 's/./[^&]*/g' <<< "${SEARCH}")
OCCURRENCE=3 
REPLACE="FOUR" 
SED_DELIM=$'\001'  
sed -r "s${SED_DELIM}${SEARCH}((${SEARCHNEG}${SEARCH}){$((${OCCURRENCE}-1))}${SEARCHNEG})\$${SED_DELIM}${REPLACE}\1${SED_DELIM}"  <<< "one one two two one one three three one one"

Friday, February 26, 2016

Decoding Black Knight Satellite -- Recon

#!/usr/bin/env bash 

#############################################################################
###########################################################################
### Created by A.M.Danischewski (c) 2016 v1.00
### Issues: If you find any issues emai1 me at my <first name> dot 
###         <my last name> at gmail dot com.  
###
### This program is intended to facilitate the recording of the Live ISS 
### feed at http://www.ustream.tv/channel/live-iss-stream
### 
### I noticed that the downloaded files offered on the Ustream servers 
### seldom matched what I was viewing on the realtime stream from the 
### website. 
###
###  See the following for more background on the Black Knight Satellite: 
###    https://www.youtube.com/watch?v=3RmSKT-9u_A 
###    https://www.youtube.com/watch?v=eO6a_e2u0c4
### 
### To use this software, configure the download location variable below
### and add the aliases to your ~/.bashrc file. Then periodically open a 
### webbrowser to: http://www.ustream.tv/channel/live-iss-stream
###
### If you see anything interesting, type $> rbk and make sure the webbrowser
### window remains visible (it records exactly what you see on your desktop
### screen). When the anomolous/interesting activity is over, go back to 
### the recording terminal window and hit Ctrl-C to stop the recording. 
### Afterward you can view the recent recording by typing in $> vbk. 
###
### Upload your findings to Youtube as soon as possible. 
###  
### This program requires (to work to full capacity) by default: 
### bash, avconv/ffmpeg, vlc 
### 
### Other useful software, youtube-dl for downloading youtube videos: 
###   https://rg3.github.io/youtube-dl/
### 
### This program is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
###########################################################################
#############################################################################

########  ### CHANGE ###  ### OUTPUT DIR ###  CHANGE THIS #### 
## Change the following to the location of a large drive where you 
## want the desktop recordings to live. 
##
 declare OUTPUTDIR="/mnt/seagate1/ISS/" ### CHANGE THIS 
##
#################### END CHANGE 

 ## These should be sensible for most people. 
declare FILE_PREFIX="ISS_$(date +%Y%m%d)"
declare RESOLUTION="1280x720" 
declare FRAMERATE="25" 
declare AVCONVPROG="$(which ffmpeg || which avconv)" 
declare DISCARD_DEV=/dev/random  ## If not on Linux, change to /dev/null
declare VIDEOCODEC="libx264" 
 ## If you are on Crouton or other chroot, change this (E.g. ":1.0+0,0")
declare CAPTUREDISPLAY=":0.0+0,0" 
declare OUTPUTSUFFIX="mkv" 

function get_max_iss_seq() {
 MAXSEQ=$( { ls -p "${OUTPUTDIR%/}/${FILE_PREFIX}"* | tr '.' '_' | grep -E "${FILE_PREFIX}_[0-9]*" | sort -n -t _ -k 3 | tail -1 | cut -d_ -f3; } 2>"${DISCARD_DEV}")
 echo "$((${MAXSEQ}+1))"
} 

function print_aliases() {  
cat << EOF
alias go2iss='cd "${OUTPUTDIR}"'  
alias rbk='${0} -r' 
alias arbk='${0} -ar' 
alias vbk='go2iss; vlc "\$(ls -tr ISS* | tail -1)"' 
EOF
} 

(($#==0)) && echo "Usage: ${0##*/} [-r (record)] [-ar (record with audio)] [-p (print aliases)]" && exit 0 
[[ ! -z "${1}" && "${1}" =~ ^-p ]]  && print_aliases && exit 0 
[[ ! -z "${1}" && "${1}" =~ ^-r ]]  && "${AVCONVPROG}" -f x11grab -r ${FRAMERATE} -s ${RESOLUTION} -i "${CAPTUREDISPLAY}" -vcodec ${VIDEOCODEC} -pre lossless_ultrafast -threads 0  "${OUTPUTDIR%/}/${FILE_PREFIX}_$(get_max_iss_seq).${OUTPUTSUFFIX}" && exit 0 
[[ ! -z "${1}" && "${1}" =~ ^-ar ]] && "${AVCONVPROG}" -preset medium -f alsa -i pulse -f x11grab -r ${FRAMERATE} -s ${RESOLUTION} -i "${CAPTUREDISPLAY}" -vcodec ${VIDEOCODEC} -threads 0 -aq 10 -af "volume=volume=10dB:precision=fixed" -ar 44100 -crf 23 "${OUTPUTDIR%/}/${FILE_PREFIX}_$(get_max_iss_seq).${OUTPUTSUFFIX}" && exit 0 

Monday, February 1, 2016

Print Greek in Bash

alias print_greek='declare -A na_array=(["0380"]=1  ["0381"]=1  ["0382"]=1  ["0383"]=1  ["038B"]=1  ["038D"]=1  ["0378"]=1  ["0379"]=1 ["037F"]=1 ["03A2"]=1 ); for uprefix in 037 038 039 03A 03B 03C 03D 03E 03F; do for usuffix in {0..9} {A..F}; do [[ -z $(echo "${na_array["${uprefix}${usuffix}"]+check}") ]] && printf "\u${uprefix}${usuffix}\n"; done; done;' 

Sunday, January 31, 2016

Simple Webscraper with PhantomJs!

////////////////////////////////////////////////////////// 
/////  PhantomJS URL Scraper v.1.3 ///// 
// 
// Copyrighted by +A.M.Danischewski  2016+ (c)
// This program may be reutilized without limits, provided this 
// notice remain intact. 
// 
// Usage: phantomjs phantom_urls.js <URL> [["class"|"id"] [<query id/class name>]]
//
//   Argument 1: URL -- "https://www.youtube.com/watch?v=8TniRMwL2Vg" 
//   Argument 2: "class" or "id" 
//   Argument 3: If Argument 2 was provided, "class name" or "id name" 
// 
// By default this program will display ALL urls from a user supplied URL.  
// If a class name or id name is provided then only URL's from the class 
// or id are displayed.  
//  
/////////////////////////////////// 

var page = require('webpage').create(), 
    system = require('system'),
    address;

if (system.args.length === 1) {
  console.log(' Usage: phantomjs phantom_urls.js <URL> [["class"|"id"] [<query id/class name>]]');
  phantom.exit();
}

address = system.args[1];
querytype= system.args[2];
queryclass = system.args[3];
page.open(address, function(status) {
  if (status !== 'success') {
    console.log('Error loading address: '+address);
  } else {
   //console.log('Success! In loading address: '+address);   
  }
});

page.onConsoleMessage = function(msg) {
  console.log(msg);
}

page.onLoadFinished = function(status) {
   var dynclass="function() { window.class_urls = new Array(); window.class_urls_next=0; var listings = document.getElementsByClassName('"+queryclass+"'); for (var i=0; i < listings.length; i++) { var el = listings[i]; var ellnks=[].map.call(el.querySelectorAll('a'),function(link) {return link.getAttribute('href');}); var elhtml=el.innerHTML; window.class_urls.push(ellnks.join('\\n')); }; return window.class_urls;}"; 
   var    dynid="function() { window.id_urls = new Array(); window.id_urls_next=0; var listings = document.getElementById('"+queryclass+"'); var ellnks=[].map.call(listings.querySelectorAll('a'),function(link) {return link.getAttribute('href');}); var elhtml=listings.innerHTML; window.id_urls.push(ellnks.join('\\n'));  return window.id_urls;}";  
   var  allurls="function() { var links = page.evaluate(function() { return [].map.call(document.querySelectorAll('a'), function(link) { return link.getAttribute('href'); };); };); console.log(links.join('\\n')); }"; 
   var page_eval_function="";  
   if (querytype === "class") {
   console.log(page.evaluate(dynclass).toString().replace(/,/g, "\n")); 
   } else if (querytype === "id") {
   console.log(page.evaluate(dynid).toString().replace(/,/g, "\n")); 
   } else { 
   var links = page.evaluate(function() {
        return [].map.call(document.querySelectorAll('a'), function(link) {
            return link.getAttribute('href');
        });
    });    
       console.log(links.join('\n'));
   }             
   phantom.exit();
};

Wednesday, January 20, 2016

cp to Multiple Destinations - cpm

alias cpm='_() { src="${1%/}"; shift; printf "\"%s\" " "$@" | xargs -n 1 cp -vR "${src}"; }; _' 

Wednesday, January 6, 2016

To the Clipboard! In Bash

#!/usr/bin/env bash

###     Copyrighted +A.M.Danischewski (c)2016+  
### You may reuse this software without limit provided 
###         this notice remain in tact. 
###
### File: clip.bsh
### Requires: xsel 
###  Description: This script copies something to the clipboard, I 
###  recommend a simple alias, such as: $> alias clip='clip.bsh' 
###  Then you can:    
###     $> echo "hi there" | clip 
###     $> clip myblogpost.html
###     $> clip <<< "little message" 
###  _-=  Enjoy!  _-=
  
declare cliptxt="${1}"
declare rdlnk=$(readlink /proc/$$/fd/0)
declare nl=$(echo -en "\x01") 
if grep -Eq "^pipe:|deleted" <<< "${rdlnk}"; then 
 [[ ! -z "${cliptxt}" ]] && cliptxt=""
 while IFS= read -d $'\n' -r piped_input || break; do cliptxt="${cliptxt}${piped_input}${nl}"; done  
elif [[ -f "${rdlnk}" ]]; then   ## Its a redirected file
 cliptxt=$(< "${rdlnk}") 
elif [[ -e "${cliptxt}" ]]; then ## Its a filename
 cliptxt=$(< "${cliptxt}")       ## File name proper no redirect
else 
 echo " *** Something is wrong, input not read by ${0}." 
fi 
echo -En "${cliptxt}" | tr "${nl}" "\n" | xsel -ib
exit 0 

Bash Sound Fader

#!/usr/bin/env bash 

###     Copyrighted +A.M.Danischewski (c)2016+  
### You may reuse this software without limit provided 
###         this notice remain in tact. 
###
### File: fader.bsh   
###  Description: Simple starter framework for sound manipulation. 
###     $> alias fade='fader.bsh' 
###     $> fade 90 
###  Note: If its broken for some reason, perhaps you have a different 
###  sound card configuration, don't use Alsa/Pulse etc. 
###  To fix it find a way to make the following commands work, and 
###   search and replace them in the code below: 
### 
###   getvol -- The next command should return an integer of the current 
###             volume level:
###    amixer -D pulse sget Master | sed -n "/Left: Playback/p" | \
###            grep -o "\[[0-9]*\%" | sed "s/^.//;s/.\$//" 
### 
###   setvol -- where ${a} is any integer, should set the volume: 
###    amixer -D pulse sset Master ${a}% &>"${DISCARD_DEV}" 
###
###  _-=  Enjoy!  _-=  

declare fade_step=${2:-.05}
declare target_vol=${1}
declare DISCARD_DEV="/dev/random" 

(($#==0)) || [[ "${1}" =~ ^- ]] && usage

function usage() {   
 echo " Usage: fade <target volume> <fade_speed [.05-10]>" 
 exit 0 
} 

function getvol() { 
amixer -D pulse sget Master | sed -n "/Left: Playback/p" | \
          grep -o "\[[0-9]*\%" | sed "s/^.//;s/.\$//"
}

function sanity_checks() { 
((${target_vol}>100)) && target_vol=100 
((${target_vol}<0))   && target_vol=0 
}

function fade() { 
local curr_vol=$(getvol)
for a in $(eval echo {${curr_vol}..${target_vol}}); do 
 amixer -D pulse sset Master ${a}% &>"${DISCARD_DEV}" 
 sleep ${fade_step}
done 
}

function main() { 
sanity_checks
fade &
}

main 
exit 0 

Monday, January 4, 2016

Numbers to Words! In Bash

#!/usr/bin/env bash

###     Copyrighted +A.M.Danischewski (c)2016+  
### You may reuse this software without limit provided 
###         this notice remain in tact. 
### Version: 1.03
### File: num2str.bsh   
###  Description: This script turns numbers into words! 
###     $> num2str.bsh 112975
###        One Hundred Twelve Thousand Nine Hundred Seventy Five
###     $> num2str.bsh 112975 anyflag ## More verbose! 
###        One Hundred Twelve Thousand Nine Hundred Seventy Fifth
###     $> num2str.bsh 1
###        One 
###     $> num2str.bsh 
###        First
###  _-=  Enjoy!  _-=  

declare -a units=("" "one" "two" "three" "four" "five" "six" "seven" \
                  "eight" "nine" "ten" "eleven" "twelve" "thirteen" "fourteen" \
                  "fifteen" "sixteen" "seventeen" "eighteen" "nineteen")            
declare -a tens=("" "" "twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty" "ninety")
declare -a unitsverbose=("" "first" "second" "third" "fourth" "fifth" "sixth" \
                         "seventh" "eighth" "ninth" "tenth" "eleventh" "twelfth" "thirteenth" \
                         "fourteenth" "fifteenth" "sixteenth" "seventeenth" "eigteenth" \
                         "nineteenth")
declare numstr="${1}" 
declare rdlnk=$(readlink /proc/$$/fd/0)

if grep -Eq "^pipe:|deleted" <<< "${rdlnk}"; then 
 [[ ! -z "${numstr}" ]] && numstr="" && set -- ourdearflag again
 while IFS= read -r piped_input || break; do numstr="${numstr}${piped_input}"; done  
elif [[ -f "${rdlnk}" ]]; then 
 [[ ! -z "${numstr}" ]] && numstr="" && set -- ourdearflag again
 numstr=$(head -1 "${rdlnk}") ## Only line 14u, you want more than h4ck.
elif [[ -e "${numstr}" ]]; then 
 numstr=$(head -1 "${numstr}") ## File name proper no redirect.
fi 

function main() { 
 local tmpnum=""
 local tmpnumv="" 
 if (($# > 1)); then 
   ## If more than 2 digits, convert only the ((last digit) (if > 0)) or last 2 digits.
  if ((${#numstr} > 2)); then 
   tmpnumv=$(sed 's/^\(.*\)\(..$\)/\2/' <<< "$numstr")
   tmpnum="$(sed 's/..$//' <<< "$numstr")00"
   tmpnum=$(convert ${tmpnum})
   numstr=$((10#${tmpnumv}))
   tmpnumv=$(convert ${tmpnumv} "unitsverbose")
   ((${#numstr} == 2)) && ((${numstr}>19)) && ((${numstr:1:1}==0)) && tmpnumv="$(sed 's/y$//' <<< "${tmpnumv}")ieth"
   numstr="${tmpnum} ${tmpnumv}"
  elif ((${#numstr} == 2)) && ((${numstr}>19)); then 
    numstr="$(sed 's/y$//' <<< $(convert "${numstr}" "unitsverbose"))ieth"
  else ## Convert the whole number to verbose
   numstr=$(convert "$numstr" "unitsverbose")
  fi 
   grep -qEi 'hundred$|thousand$|million$|billion$' <<< "${numstr}" && numstr="${numstr}th"
 else ## Normal conversion 
   numstr=$(convert "$numstr") 
 fi 
  ## Temp, fix for 329478932 and other large numbers that may cause a double space. 
 sed 's/[ ]*$//;s/  / /g' <<< "${numstr}"
} 
   
function convert() {
local -i INTEGER=$((10#${1}))
local unitstype=${2:-"units"} ## units or unitsverbose
 if (($INTEGER < 0)); then 
   echo -en "minus "
   convert $(($INTEGER*-1)) 
elif (($INTEGER < 20)); then 
   eval echo -en \${${unitstype}[$INTEGER]}
elif (($INTEGER < 100)); then 
   echo -en ${tens[$(($INTEGER/10))]}  
   (($INTEGER%10)) && echo -en " "
   eval echo -en \${${unitstype}[$(($INTEGER%10))]}
elif (($INTEGER < 1000)); then 
   eval echo -en "\${${unitstype}[$(($INTEGER/100))]} hundred" 
   (($INTEGER%100)) && echo -en " "
   convert $(($INTEGER%100)) 
elif (($INTEGER < 1000000)); then 
   convert $(($INTEGER/1000))
   echo -en " thousand" 
   (($INTEGER%1000)) && echo -en " "
   convert $(($INTEGER%1000)) 
elif (($INTEGER < 1000000000)); then 
   convert $(($INTEGER/1000000))
   echo -en " million " 
   (($INTEGER%1000)) && echo -en " "
   convert $(($INTEGER%1000000)) 
else 
   convert $(($INTEGER/1000000000))
   echo -en " billion" 
   (($INTEGER%1000000000)) && echo -en " "
   convert $(($INTEGER%1000000000)) 
fi 
} 

main $@ | sed 's/^./\U&/;s/ [^ ]/\U&/g'
exit 0

Sunday, January 3, 2016

Word dılɟ! in Bash

#!/bin/bash

### Copyrighted +A.M.Danischewski (c)2015+  
### You may reuse this software without limit provided this notice 
### remain in tact. 
###
### File: wordflip.bsh  
###  Description: This script turns text upside down! =) 
###  It can accept piped data and redirects,
###     $> wordflip.bsh <<< "some txt" 
###     $> echo -en "flip\nme\n" | wordflip.bsh
###  _-=  Enjoy!  _-=  

declare word=""
declare -A wordlist 
wordlist["a"]="\u0250" 
wordlist["b"]="q" 
wordlist["c"]="\u0254" 
wordlist["d"]="p" 
wordlist["e"]="\u01dd" 
wordlist["f"]="\u025f" 
wordlist["g"]="\u0183"
wordlist["h"]="\u0265"
wordlist["i"]="\u0131"
wordlist["j"]="\u027e"
wordlist["k"]="\u029e"
wordlist["l"]="l"
wordlist["m"]="\u026f"
wordlist["n"]="u"
wordlist["o"]="o"
wordlist["p"]="d"
wordlist["q"]="b"
wordlist["r"]="\u0279"
wordlist["s"]="s"
wordlist["t"]="\u0287"
wordlist["u"]="n"
wordlist["t"]="\u0287"
wordlist["v"]="\u028c"
wordlist["w"]="\u028d"
wordlist["x"]="x"
wordlist["y"]="\u028e"
wordlist["z"]="z"
wordlist["]"]="["
wordlist["["]="]"
wordlist[","]="'"
wordlist["'"]=","
wordlist["("]=")"
wordlist[")"]="("
wordlist["{"]="}"
wordlist["}"]="{"
wordlist["?"]="\u00bf"
wordlist["!"]="\u00a1"
wordlist["\""]=","
wordlist[">"]="<"
wordlist["<"]=">"
wordlist["+"]="+"
wordlist["_"]="\u203e"
wordlist[";"]="\u061b"

 ## Handle piped input and here-string redirects. 
if readlink /proc/$$/fd/0 | grep -Eq "^pipe:|deleted"; then
 word=""
 while IFS= read -r PIPED_INPUT || { DONE=1; }; do 
  PIPED_INPUT=$(sed 's#\\#\\\\#g' <<< "${PIPED_INPUT}")
  word="${word}${PIPED_INPUT}+"
  ((${DONE})) && break; 
 done
else 
 word="${1}" 
fi 

revword=$(echo "$word"|rev) 
for i in $(eval echo "{1..${#revword}}"); do 
 printf "${wordlist[${revword:$((${i}-1)):1}]}"
done | sed 's/^+*//' | tr '+' '\n' 
echo 
exit 0