3 ms·
Here's the opposite of your approach, using only basic POSIX shell techniques... #!/bin/sh # trim left space triple ' '* lt() { s="$1"; while [ ! "${s
by saltcured 5y ago
Here's the opposite of your approach, using only basic POSIX shell techniques...
#!/bin/sh
# trim left space triple ' '*
lt() { s="$1"; while [ ! "${s## }" = "$s" ]; do s="${s## }"; done; printf "%s" "$s"; }
# trim right space ' '*
rt() { s="$1"; while [ ! "${s%% }" = "$s" ]; do s="${s%% }"; done; printf "%s" "$s"; }
# count months for first/last special treatment
n=1
# usage: reform pos line1 line2 ... line7
reform() {
o=$1; m="$(printf "%s" $(expr substr "$2" $o 20))"; l1="$(expr substr "$3" $o 20)"
[ $n -ne 1 ] && l1="$(lt "$l1")" # suffix of spliced week
shift 3
printf "%s %s\n" "$l1" "$m"
while [ "$#" -gt 0 ]; do
l="$(expr substr "$1" $o 20 )"; lx="$(rt "$l")"; shift
if [ -z "$lx" ]; then
:
elif [ "$l" = "$lx" -o $n -eq 12 ]; then
printf "%s\n" "$lx" # whole week
elif [ -n "$lx" ]; then
printf "%s " "$lx" # prefix of spliced week
fi
done
n=$(( $n + 1 ))
}
# buffer 8 lines into arg vector via recursion hack
# then replace lines 3x to project out 3 months in this row
buffer() {
if [ "$#" -eq 7 ]; then
reform 1 "$@"; reform 24 "$@"; reform 47 "$@"
else
IFS= read line || return 1
[ "$#" -eq 0 ] && read discard
buffer "$@" "$line"
fi
}
# strip preamble and process 4 rows of months
process() { read discard; read discard; for i in 1 2 3 4; do buffer; done; }
cal -y ${1:-2021} | process
- 1vuio0pswjnm7 5y agoexpr is not part of the shell, it is a separate program