Last active
January 11, 2022 11:52
-
-
Save kou1okada/9e7ed46c0defd6a3b9041a576f40361e to your computer and use it in GitHub Desktop.
zs.sh - ZipS: Choose the best compression.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# zs.sh - ZipS: Choose the best compression | |
# Copyright (c) 2018 Koichi OKADA. All rights reserved. | |
# This script is distributed under the MIT license. | |
# | |
(( 5 <= DEBUG )) && set -x | |
function usage () | |
{ | |
cat<<-EOD | |
Usage: ${0##*/} [options] [files ...] | |
Options: | |
-h, --help | |
-f, --force | |
-p, --progress | |
-v, --verbose | |
EOD | |
} | |
function optparse () | |
{ | |
ARGS=() | |
while (( 0 < $# )); do | |
case "$1" in | |
-h|--help) | |
OPT_HELP="$1" | |
shift | |
;; | |
-f|--force) | |
OPT_FORCE="$1" | |
shift | |
;; | |
-p|--progress) | |
OPT_PROGRESS="$1" | |
shift | |
;; | |
-v|--verbose) | |
OPT_VERBOSE="$1" | |
shift | |
;; | |
--) | |
ARGS+=( "${@:2}" ) | |
shift $# | |
;; | |
-*) | |
error "Unknown option: $1" | |
exit 1 | |
;; | |
*) | |
ARGS+=( "$1" ) | |
shift | |
;; | |
esac | |
done | |
if [ -n "$OPT_HELP" ]; then | |
usage | |
exit | |
fi | |
} | |
SGR_reset="\e[0m" | |
SGR_bold="\e[1m" | |
SGR_red="\e[31m" | |
SGR_green="\e[32m" | |
SGR_yellow="\e[33m" | |
EL="\e[K" | |
function error () | |
{ | |
echo -e "${SGR_red}${SGR_bold}Error:${SGR_reset} $@" | |
} >&2 | |
function warning () | |
{ | |
echo -e "${SGR_yellow}${SGR_bold}Warning:${SGR_reset} $@" | |
} >&2 | |
function prepare () | |
{ | |
local i | |
ZS=() | |
_ZS=( GZIP BZIP2 XZ LZO LZ4 BROTLI ZSTD ) | |
GZIP=( gzip .gz {1..9} ) | |
BZIP2=( bzip2 .bz2 {1..9} ) | |
XZ=( xz .xz {1..9} ) | |
LZO=( lzop .lzo {1..9} ) | |
LZ4=( lz4 .lz4 {1..9} ) | |
BROTLI=( brotli .br {1..9} ) | |
ZSTD=( zstd .zst {1..19} ) | |
GZIP_OPT=( -q ) | |
BZIP2_OPT=( -q ) | |
XZ_OPT=( -q ) | |
LZO_OPT=( -q ) | |
LZ4_OPT=( -q ) | |
BROTLI_OPT=( ) | |
ZSTD_OPT=( -q ) | |
EXTS=() | |
for i in "${_ZS[@]}"; do | |
if eval "which \${${i}[0]} >&/dev/null"; then | |
ZS+=( "$i" ); | |
eval "EXTS+=( \"\${${i}[1]}\" )" | |
fi | |
done | |
} | |
function zs () | |
{ | |
local i Z ZZ | |
local SIZE CMD OPT EXT LEV | |
local MINSIZE=$( stat -c %s "$1" ) | |
local MINCMD=( true ) | |
local MINEXT= | |
local PARAM=() | |
if [ -z "$OPT_FORCE" ]; then | |
for EXT in "${EXTS[@]}"; do | |
if [ -e "$1$EXT" ]; then | |
warning "Compressed file already exists: $1$EXT" | |
echo "Skip it." | |
return 1 | |
fi | |
done | |
fi | |
for ZZ in "${ZS[@]}"; do | |
eval "Z=( \"\${${ZZ}[@]}\" )" | |
eval "OPT=( \"\${${ZZ}_OPT[@]}\" )" | |
CMD=( "${Z[0]}" "${OPT[@]}" ) | |
EXT="${Z[1]}" | |
LEV=( "${Z[@]:2}" ) | |
for i in "${LEV[@]}"; do | |
"${CMD[@]}" -$i -f -k "$1" | |
SIZE=$( stat -c %s "$1$EXT" ) | |
rm "$1$EXT" | |
if (( SIZE < MINSIZE )); then | |
MINSIZE=$SIZE | |
MINCMD=( "${CMD[@]}" ) | |
MINEXT=$EXT | |
PARAM=( -$i -f ) | |
fi | |
[ -n "$OPT_PROGRESS" ] && printf "${EL}%-6s %2d %'16d %s\r" "$CMD" "$i" "$SIZE" "$1$EXT" | |
done | |
done | |
"${MINCMD[@]}" "${PARAM[@]}" "$1" | |
[ -n "$OPT_PROGRESS" -o -n "$OPT_VERBOSE" ] && printf "${EL}%-6s %2d %'16d %s\n" "$MINCMD" "${PARAM:1}" "$MINSIZE" "$1$MINEXT" | |
} | |
optparse "$@" | |
set -- "${ARGS[@]}" | |
prepare | |
for i; do zs "$i"; done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment