ll-function initial version
authorIan Kelling <ian@iankelling.org>
Tue, 22 Apr 2014 07:16:21 +0000 (00:16 -0700)
committerIan Kelling <ian@iankelling.org>
Fri, 9 Sep 2016 21:06:13 +0000 (14:06 -0700)
ll-function [new file with mode: 0644]

diff --git a/ll-function b/ll-function
new file mode 100644 (file)
index 0000000..fac9010
--- /dev/null
@@ -0,0 +1,88 @@
+#!/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
+}
+