Skip to content

Instantly share code, notes, and snippets.

@iav
Created September 23, 2019 12:53
Show Gist options
  • Save iav/870608a60088c24c553a9080d138cc91 to your computer and use it in GitHub Desktop.
Save iav/870608a60088c24c553a9080d138cc91 to your computer and use it in GitHub Desktop.
#!/bin/sh
#
# IDENTIFICATION
# $RCSfile$ $Revision$ $Date$
#
# NAME
# dull - Eine Mischung aus ls -la + du -k
#
# SYNOPSIS
# dull [ -a | -s | -t | -- ]
#
# DESCRIPTION
# combination of 'du' and 'ls -l', lists directory entries preceded by
# recursive disk usage; this is especially useful in directories where
# there are items owned my various accounts, and you want to see sizes
# and owner in one listing; also gives total blocks;
#
# erstellt eine Ausgabe in der Form:
# 229 drwxr-xr-x 3 a101xxx oe352 512 Jan 22 16:58 bin/
# .
# .
#
# EXPIRATION DATE
# -keines-
#
# OPTIONS
# -a abbreviated listing (fewer columns);
# -s sort output by size;
# -t do not print the total;
# -- stop processing options;
# item what to analyze;
# default is everything in the current directory;
#
# OPERANDS
# -keine-
#
# GLOBALE VARIABLES
# -keine-
#
# FILES
# -keine-
#
# EXIT STATUS
# -keiner-
#
# USAGE
# -keine-
#
#
# CREATION DATE
# 2002-01-22
#
#
# ==============================================================================
PROG=`basename "$0"`
USAGE="
Usage: $PROG [-ast] [--] [item...]
Output is a mix from the 'du' and 'ls -l' commands.
-a abbreviated listing (fewer columns);
-s sort output by size;
-t do not print the total;
-- stop processing options;
item what to analyze; default is everything in the
current directory;
"
#
# Note: in several instances below, some effort is made to determine
# proper forms of commands; this is usually to distinguish between
# BSD and ATT styles, such as differences between SunOS and Solaris;
#
ABBREV=0 # don't abbreviate output
SORT=0 # don't sort by size
TOTAL=1 # print the TOTAL
#
# platform specific settings
#
SYS="`uname -sr`" # OS type
AWK='awk'
case "$SYS" in
'SunOS '*)
AWK="nawk"
esac
SYNTAX="
$PROG: option syntax error."
syntax_error() {
echo "$SYNTAX" >&2
echo "$USAGE" >&2
exit 1
}
arg_syntax_check() {
[ "$1" -lt 2 ] && syntax_error
}
while [ $# != 0 ]; do
OPT="$1"
case "$OPT" in
# option without argument
-a)
# print out a more abbreviated listing, ie, fewer columns
ABBREV=1
;;
-s)
# sort output by size
SORT=1
;;
-t)
# do not print the total
TOTAL=0
;;
# option with argument
# -c)
# CFLAG=1
# arg_syntax_check "$#"
# CARG="$2"
# shift
# ;;
# ...
--)
shift
break
;;
# unknown option
-?)
syntax_error
;;
# compound option
-??*)
# break up a compound option
NEW_OPTS=`$AWK 'BEGIN {
OPT_STR = "'"$OPT"'";
LEN = length(OPT_STR);
NEW_OPTS = "";
STATUS = 0;
for (POS=2; POS+0 <= LEN; ++POS) {
OPT = substr(OPT_STR,POS,1);
if (OPT !~ /[a-zA-Z0-9_]/)
STATUS = 1;
NEW_OPTS = NEW_OPTS " -" OPT;
}
print NEW_OPTS;
exit STATUS;
}' <&-` || {
syntax_error
}
shift
if [ "$#" -gt 0 ]; then
set -- $NEW_OPTS "$@"
else
set -- $NEW_OPTS
fi
continue
;;
# end of options, just command arguments left
*)
break
esac
shift
done
#
# if no arguments, just use the current directory;
# these become the positional parameters;
# if only one argument and it is a directory, then
# cd to it and do the same;
#
if [ $# = 0 -o \( $# = 1 -a -d "$1" \) ]; then
[ $# = 1 ] &&
cd "$1"
# restrict field separator to newline only
_IFS="$IFS"
IFS='
'
set -- X `ls -A`
shift
if [ $# = 0 ]; then
exit 0
fi
IFS="$_IFS"
fi
#
# figure out which form of 'du' to use
#
get_pathname() {
set -- `type $1`
[ $? != 0 ] && return 1
shift 2
echo "$*"
return 0
}
DU=`get_pathname du`
if [ $? != 0 ]; then
echo NO
echo "
$PROG: cannot find \"du\" command." >&2
exit 1
fi
if $DU -sk $DU >&- 2>&-; then
DU="du -sk"
else
DU="du -s"
fi
#
# figure out which form of 'ls' to use,
# longer one wins
#
LEN1=`expr "\`ls -ld /\`" : '.*'`
LEN2=`expr "\`ls -ldg /\`" : '.*'`
if [ "$LEN1" -gt "$LEN2" ]; then
LS="ls -ldF"
SLEN="$LEN1"
else
LS="ls -lgdF"
SLEN="$LEN2"
fi
#
# now operate on each selected item
#
for ITEM do
# don't get hosed by arguments that start with '-'
case "$ITEM" in
-*)
ITEM="./$ITEM"
esac
# make sure it exists
ls -d "$ITEM" >/dev/null ||
continue
$DU "$ITEM" 2>&-
$LS "$ITEM" 2>&-
done |
$AWK 'BEGIN {
# grab some values from the shell
ABBREV = '"$ABBREV"';
SLEN = '"$SLEN"';
SORT = '"$SORT"';
TOTAL = '"$TOTAL"';
SORT_CMD = "sort +0n"
}
{
#
# odd lines are du output
# even lines are ls output
#
if ((NR % 2) == 1) {
BLOCKS = $1;
TBLOCKS += $1;
}
else {
if (ABBREV) {
if (length($1)+0 > 10)
USER = $2;
else
USER = $3;
# blocks, user, itemname
LINE = sprintf("%8s %-8s %s",BLOCKS,USER,substr($0,SLEN));
}
else
# blocks, the whole line from ls
LINE = sprintf("%8s %s",BLOCKS,$0);
++CNT;
if (SORT)
LINES[CNT] = LINE;
else
print LINE;
}
}
END {
if (SORT) {
for (I=1; I+0 <= CNT; ++I)
print LINES[I] | SORT_CMD;
close(SORT_CMD);
}
if (TOTAL && CNT) {
printf("%8s\n",substr("--------",1,length(TBLOCKS)));
printf("%8s\n",TBLOCKS);
}
}'
exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment