dotfiles/bin/ocelot

181 lines
3.6 KiB
Bash
Executable File

#!/bin/bash
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
# ocelot -- The cute alternative to cat (with headers!) #
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
# Author: binaryDiv #
# Version: 1.1.0 #
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
# Strict mode
set -euo pipefail
IFS=$'\n\t'
BASENAME=$(basename $0)
# Global options
STYLE=big
PREFIXCHAR='#'
LINECHAR='~'
# Helper functions
# ----------------
# Prints help text
function usage {
cat << END_OF_HELPTEXT
Usage: $BASENAME [OPTION] FILE...
Prints all FILEs with their filename as a header. Like cat but more cute.
If FILE is '-', it reads from standard input.
General options:
-h print this help message
Style options:
-b show big headers (with lines above and under filename; default)
-s show single lined headers (only prefix and filename)
-n no style, just print filename and content
-p PREFIX use PREFIX in front of the header lines (default: '#')
-l LINECHAR use LINECHAR as character for lines in big headers (default: '~')
END_OF_HELPTEXT
}
# Print a single file with header
function print_file_with_header {
file=$1
print_header $file
print_file $file
echo
}
# Prints a header
function print_header {
text=$1
if [[ $text == '-' ]]; then
text='STDIN'
fi
case $STYLE in
big)
header_style_big "$text"
;;
singleline)
header_style_singleline "$text"
;;
none | *)
header_style_none "$text"
;;
esac
}
# Print error message
function print_error {
text=$1
echo "${PREFIX}[$text]"
}
# Prints content of file
function print_file {
file=$1
if [[ -f $file || -p $file || $file == '-' ]]; then
cat $file
elif [[ -d $file ]]; then
print_error "File is a directory"
else
print_error "File does not exist"
fi
}
# Define header styles
# --------------------
function header_style_none {
text=$1
echo $text
}
function header_style_singleline {
text=$1
echo "${PREFIX}${text}"
}
function header_style_big {
text=$1
length=${#text}
echo -n "${PREFIX}"; characterline $LINECHAR $length
echo "${PREFIX}${text}"
echo -n "${PREFIX}"; characterline $LINECHAR $length
}
# Print a line of characters (e.g. `characterline '#' 32`)
function characterline {
char=$1
count=$2
for (( i = 0; i < $count; i++ )); do echo -n $char; done
echo
}
# Main program
# ------------
if [[ "$@" == "--help" ]]; then
usage
exit 0
fi
# Parse shell arguments and set global variables
while getopts ":hbsnp:l:" option; do
case $option in
h)
usage
exit 0
;;
b) STYLE=big ;;
s) STYLE=singleline ;;
n) STYLE=none ;;
p) PREFIXCHAR="$OPTARG" ;;
l) LINECHAR="$OPTARG" ;;
:)
echo "$BASENAME: option -$OPTARG requires an argument" >&2
echo "Try '$BASENAME --help' for more information." >&2
exit 1
;;
?)
echo "$BASENAME: invalid option: -$OPTARG" >&2
echo "Try '$BASENAME --help' for more information." >&2
exit 1
;;
esac
done
# Remove parsed options from arguments
shift $(($OPTIND - 1))
# Set some global variables
PREFIX=
if [[ $PREFIXCHAR != '' ]]; then
PREFIX="$PREFIXCHAR "
fi
# Print all files
for file in $@; do
print_file_with_header $file
done