#!/bin/bash # Comparission script for compression tools. # Require bash V5+ # (C) 2020 - F-Hauri.ch # Licensed by GNU GENERAL PUBLIC LICENSE Version 3 # https://www.gnu.org/licenses/gpl-3.0.txt # cmds=( gzip bzip2 xz zstd zstd\ -T4) # decmds=(zcat:gz bzcat:bz2 xzcat:xz zstdcat:zst ) cmds=( gzip:gz bzip2:bz2 xz:xz zstd:zst brotli:b) decmds=(zcat:gz bzcat:bz2 xzcat:xz zstdcat:zst brotli\ -d:b) numtry=3 txtsize() { local _idx=$(( $1 > 1125899906842623 ? 5 : $1 > 1099511627775 ? 4 : $1 > 1073741823 ? 3 : $1 > 1048575 ? 2 : $1 > 1023 ? 1 : 0 )) \ _abr=(b K M G T P) local _res=000$((1000*$1/(1024**_idx))) printf -v $2 %.2f%s ${_res::-3}.${_res: -3} ${_abr[_idx]} } percent() { local _pct=000$(($1*100000/$2)) printf -v $3 %.2f%% ${_pct::-3}.${_pct: -3} } musec2str () { local -n _result=$2; local _elapsed=000000$1 printf -v _elapsed "%0.4f" ${_elapsed::-6}.${_elapsed:${#_elapsed}-6} TZ=UTC printf -v _result "%(%Y %j %H %M %S)T" ${_elapsed%.*} _elapsed=.${_elapsed#*.} _elapsed=${_elapsed%%*(0)} _elapsed=${_elapsed%.} [ "$_elapsed" ] && printf -v _elapsed %-4s $_elapsed && _elapsed=${_elapsed// /0} || unset _elapsed _result=($_result) _result=$((10#$_result-1970)) _result[1]=$((10#${_result[1]}-1)) printf -v _result "%dy %dd %.0fh %.0f' %.0fs" ${_result[@]} _result=($_result) printf -v _result "%s" ${_result[@]#0?} [ "${_result#*s}" ] && { [ "$_elapsed" ] && _result+=0 } || { [ "$_elapsed" ] || _result=${_result%s}\" ;} _result=(${_result%s}${_elapsed}${_elapsed+\"}) } printf "%-20s %14s %8s %7s %15s %15s\n" File Size HSize Prct {C,Dec}ompression for file;do output=() # Doing full read instead of ``stat -c %s'' to prevent cache inequity fsize=$(LANG=C wc -c <"$file") txtsize $fsize hfsize printf "%-20s %14u %8s 100.00%%\n" "$file" $fsize "$hfsize" for cmd in "${cmds[@]}";do IFS=: read cmd ext <<<$cmd sort=() for ((i=numtry;i--;)) ;do start=${EPOCHREALTIME//.} $cmd < "$file" >/dev/null sort[${EPOCHREALTIME//.}-start]= done sort=(${!sort[@]}) output+=($sort) done . <( echo -n "tee <'$file' > " for((i=0;i<${#cmds[@]};i++)){ printf ">(%s >'$file'.%s) " "${cmds[i]%:*}" ${cmds[i]#*:} ;} ) wait for ((i=3;i--;)){ sync;((i))&&sleep .2;} # Force wait sync... for decmd in "${decmds[@]}";do IFS=: read decmd ext <<<$decmd musec2str $output hcomp output=("${output[@]:1}") csize=$(LANG=C wc -c <"$file".$ext) txtsize $csize hsize percent $csize $fsize prct sort=() for ((i=numtry;i--;)) ;do start=${EPOCHREALTIME//.} $decmd < "$file".$ext >/dev/null sort[${EPOCHREALTIME//.}-start]= done elap=(${!sort[@]}) musec2str $elap hdeco printf "%-20s %14u %8s %7s %15s %15s\n" "$file.$ext" \ $csize $hsize $prct $hcomp $hdeco done | sort -t \\0 -nk 1.21 . <(printf rm;printf " ${file@Q}.%s" ${decmds[@]#*:};echo) done