#!/bin/bash # Copyright (C) 2014 Ian Kelling # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ls -lA with enhanced formatting # octal permissions # omited acl type specifier # better hard link count: number of subdirectories or number of linked files or omitted if 0 # better human readable size # more natural date/time format for my American raised eyes ll() { local x y z q perm padding line binls sizePadding middle tail size local -a lines binls=$(type -P ls) local first=true local aclchar=false # there's no way to tell if ls uses the acl specifier unless we loop over the data twice # the 11th char is either # . for selinux context # + for any other kind of acl # or blank for no other kind of acl # I don't want to see this generally. while read line; do lines+=("$line") [[ ! ${line:10:11} == " " ]] && aclchar=true done< <( "$binls" -lAh --color=always "--time-style=+%m-%d %Y %m-%d %I:%M %p" "$@" ) for line in "${lines[@]}"; do # very first line starts with some non printing chars if $first; then line=${line#$'\E[00m'} first=false fi if ! [[ $line == [-dscbl][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xtT]* ]]; then printf "%s\n" "$line" else perm=0 for (( x=0; x<=8; x++ )); do y=${line:$(( -1*x + 9 )):1} [[ $y == [tT] ]] && perm=$(( perm + 512 )) if [[ $y == [sS] ]]; then [[ $x == 3 ]] && perm=$(( perm + 1024 )) [[ $x == 6 ]] && perm=$(( perm + 2048 )) fi [[ $y != [-ST] ]] && perm=$(( perm + 2**x )) done if $aclchar; then y="${line:11}" else y="${line:10}" fi t="${y#"${y%%[![:space:]]*}"}" # remove any initial spaces hardLinks="${t%%[[:space:]]*}" # remove everything beyond first word z=$(( ${#y} - ${#t} + ${#hardLinks} )) # length of hardlink string including padding middle=${y#*[^ ]* } size=${middle#*[^ ]* *[^ ]* } middle=${middle%"$size"} tail=${size#*[^ ]* } size=${size%"$tail"} declare -i sizePadding="${#size} - 1" size=( $size ) # remove spaces size=${size/.?/} # ignore the hardlinks that files/dirs always have if [[ ${line:0:1} == d ]]; then hardLinks=$(( hardLinks - 2 )) else hardLinks=$(( hardLinks - 1 )) fi [[ $hardLinks == 0 ]] && hardLinks= printf "%s%4o%${z}s%s%${sizePadding}s%s\n" \ "${line:0:1}" $perm "$hardLinks" " $middle" "$size" " $tail" fi done }