[clug] Going from 1 to 100 lines of ls wrapping script

Hal Ashburner hal at ashburner.info
Thu Nov 21 02:24:24 MST 2013


Given there was a little interest in the ideas around listing directories
I'll follow up.

This is the kind of thing I had in mind.
an ls function that takes all the ls options but just shows you what you
were interested in.

lsd --filter_test=h -A --color -l

to list all the symlinks, showing those beginning with a dot, with american
spelling colour output in long format. The filter_test argument is anything
accepted by test. -L -d -h or whatever.

So a couple of small requests. Please if anyone sees anything I should be
doing better I'd appreciate the review. I'm sure my bash scripting is in
general not all it could be.

But also, do you think ls should be able to filter it's output? (It's kind
of more of what -a does in a way) If so would you bet on gnu accepting a
patch?


#!/bin/bash
set -u
set -e
#set -x

# filters the output of ls
# by default to show only items that pass test -d,
# ie directories or symlinks to directories
# --filter_arg=h changes this to symlinks
# last char of lsd is d for test -d
last_char=${0:${#0}-1:1}

# this holds options to apply to ls to get the unfiltered list, eg -a
LIST_ARGS=""

# this holds options to apply to ls on each item of output, eg -l
ITEM_ARGS=""

# default argument for the filter is -d
# if you want a command that lists say symlinks, the argument to test
# is -h, so just link something ending in h to this file, eg by doing
# something like
# ln -s lsd lsh
TEST_ARG="-${last_char}"


usage()
{
    echo "${BASH_SOURCE[0]} [ --filter_test=test_arg ]"
    echo "where test_arg is a valid argument to man 1 test"
    echo "most sensible ls options should also be available"
    exit 1
}


set +e
params=$(getopt -lcolor::,author,full-time,block-size:,help,filter_test: -o
aAlrshgQf -- "$@")
retval=$?
set -e
if [[ $retval -ne 0 ]]
then
    usage
fi
eval set -- "${params}"

while [[ ${#} -gt 0 ]]
do
    case "${1}" in

    # selection and sorting options
    # applied to generate the unfiltered list
    -[aAhfr]) LIST_ARGS="${LIST_ARGS} ${1}";;

    # filtering command
    # given to test to filter what is shown
    "--filter_test") TEST_ARG=-"$(eval echo ${2})"; shift ;;

    # output formatting options
    # applied to each item in the filtered list
    -[lshgQ]) ITEM_ARGS="${ITEM_ARGS} ${1}";;
    --) shift; break;;
    "--color") ITEM_ARGS="${ITEM_ARGS} ${1}"

    #color takes an optional arg, so get it if it's there
    arg=$(eval echo $2)
    if [[ ${arg} == "always" ]] || [[ ${arg} = "never" ]] || [[ ${arg} =
"auto" ]]
    then
        ITEM_ARGS="${ITEM_ARGS}=${arg}"
    fi
    shift
;;

    "--author") ITEM_ARGS="${ITEM_ARGS} ${1}";;
    "--full-time") ITEM_ARGS="${ITEM_ARGS} ${1}";;
    "--block-size") ITEM_ARGS="${ITEM_ARGS} ${1}="${2}; shift;;
    "--help") usage ;;

    # anything else is a target dir
    *) TARGET="${TARGET:-} ${1}";;
    esac
    shift
done

/bin/ls ${LIST_ARGS} ${TARGET:-.} |
    while read item;
    do
        set +e
        test ${TEST_ARG} "${item}"
        if [[  $? -eq 0 ]]; then
            /bin/ls ${ITEM_ARGS} -d "${item}";
        fi;
        set -e
    done


More information about the linux mailing list