#!/bin/bash # ultra-fancy ultra-pointless `ls -l` alternative # compatible with bash and zsh # can be sourced or executed # to maintain zsh compatibility: # $() is surrounded in double quotes # echo -E is used to avoid \033 expanding # bare asterisks are escaped to prevent globbing # arrays are used instead of relying on word expansion # for loops over ${array[@]} as it's the only commonality I know # TODO: set better defaults for quick glances at filesize # TODO: utilize filetype; opt to strip path from output # make sure to add / to path if necessary (warning: symlinks) # TODO: include sorting somehow _lsf_begin(){ local begin=' me='$UID' '"$( awk -F: '{print "unames["$3"]=\""$1"\""}' < /etc/passwd awk -F: '{print "gnames["$3"]=\""$1"\""}' < /etc/group for x in $(groups); do echo "us[\"$x\"]=1"; done i=0;for x in bla red gre yel blu pur cya whi; do echo -E $x'="\033[3'${i}'m"' echo -n "$x" | tr '[a-z]' '[A-Z]' echo -E '="\033[1;3'${i}'m"' let i++ done )"' clr="\033[0m" BLD="\033[1m" s=1 m=60*s h=60*m d=24*h y=365*d B=1 K=1024*B M=1024*K G=1024*M T=1024*G ff["time"]="%3d%s " clr ff["size"]="%4d" clr "%s " '"$( for x in s m h d y;do echo "u[\"time,$x\"]=$x";done for x in B K M G T;do echo "u[\"size,$x\"]=$x";done ft=(-1 m m\*10 h h\*12 d d\*7 30\*d y y\*2 y\*10) fut=(s s s m m h h d d d y y) fct=(RED PUR pur YEL yel GRE gre CYA cya BLU blu BLA) fs=( 0 K K\*8 M M\*8 G G\*8 T T\*8) fus=(B B B K K M M G G T) fcs=(BLA cya CYA CYA yel yel pur pur red red) pc=(BLA WHI yel YEL blu BLU gre GRE) i=0;for x in ${ft[@]}; do echo "f[\"time,$i\"]=$x"; let i++;done echo "f[\"times\"]=$i" i=0;for x in ${fs[@]}; do echo "f[\"size,$i\"]=$x"; let i++;done echo "f[\"sizes\"]=$i" i=0;for x in ${fut[@]};do echo "fu[\"time,$i\"]=\"$x\"";let i++;done i=0;for x in ${fus[@]};do echo "fu[\"size,$i\"]=\"$x\"";let i++;done i=0;for x in ${fct[@]};do echo "fc[\"time,$i\"]=$x"; let i++;done i=0;for x in ${fcs[@]};do echo "fc[\"size,$i\"]=$x"; let i++;done i=0;for x in ${pc[@]}; do echo "pc[$i]=$x"; let i++;done )" echo -E "$begin" } _lsf_cached= lsf(){ local o_showallperm=1 o_showuser=1 o_showgroup=1 local o_mostrecent=0 opts=mgupf opt while getopts $opts'h' opt; do case $opt in f) _lsf_cached=;; p) o_showallperm=0;; u) o_showuser=0;; g) o_showgroup=0;; m) o_mostrecent=1;; ?) echo "usage: $0 [-$opts] [dir]" return 1;; esac done [ "$_lsf_cached" ] || _lsf_cached="$(_lsf_begin)" local program='BEGIN{'"$_lsf_cached"' now='"$(date +%s)"' } function printff(id, n) { len=f[id "s"] for(i=0;i<=len;i++) { idi=id "," i if(i!=len && n>f[idi]) continue unit=fu[idi] printf(fc[idi] ff[id], n/u[id "," unit], unit) break } } function trunc(str, len) { e=length(str)>len?"…":"" return substr(str,0,len-(e?1:0)) e } function fixlen(str, len) { return trunc(sprintf("%" len "s", str), len) } { printff("size", $(NF-14)) uid=$(NF-11) gid=$(NF-10) is_me=(uid==me) is_us=(gnames[gid] in us) gross=("0x" $(NF-12))+0 type=rshift(gross, 9) operm=and(gross, 07) gperm=rshift(and(gross, 070), 3) uperm=rshift(and(gross, 0700), 6) our_perm=or(or((is_me)?uperm:0, (is_us)?gperm:0), operm) printf(pc[our_perm] "%o " clr, our_perm) if('$o_showallperm') { printf(pc[uperm] "%o" clr, uperm) printf(pc[gperm] "%o" clr, gperm) printf(pc[operm] "%o " clr, operm) } if('$o_showuser') { name=fixlen((uid in unames)?unames[uid]:uid, 6) if(is_me) name=YEL name clr printf("%s ", name) } if('$o_showgroup') { name=fixlen((gid in gnames)?gnames[gid]:gid, 6) if(is_us) name=YEL name clr printf("%s ", name) } da=$(NF-4) dc=$(NF-3) dm=$(NF-2) if(!'$o_mostrecent') { printff("time", now-da) printff("time", now-dm) printff("time", now-dc) } else { max=(da>dm)?da:dm max=(max>dc)?max:dc printff("time", now-max) } # print filename by killing all fields not part of it NF-=15 print }' shift $(($OPTIND-1)) find "${1:-.}" -maxdepth 1 -print0 | xargs -0 stat -t | awk --non-decimal-data "$program" } case $- in *i*) ;; *) lsf -f esac