What is the best way to pass an alias / function to a command without degrading the functionality of the specified command?

I have an ll function that is currently expanding:

 function ll () { ls -lh --color " $@ " | grep "^d"; ls -lh --color " $@ " | grep "^-" | grep -v "~"; ls -lh --color " $@ " | grep "^l" } 

What this does is sort the specified folder, displaying folders first, then files, then links. However, I find that this approach reduces the functionality of the ls , for example, if I try to call ll /bin /tmp , I get a combination of files from both folders.

Is there a general rule for passing command aliases / functions, so that the full functionality of these commands does not decrease? If this does not happen, how can I fix my ll command to save the sort, but the full functionality of ls not lost?

Note that I currently have bash version 3.2.25 (1) -release on my system (ls version 5.97), so the --show-directories-first flag is not available to me.

EDIT:

This is the function I ended up using, I changed it a bit so that ll work without any arguments:

 function ll () { if [ $# -eq 0 ]; then set -- .; fi for d; do ls -lh --color "$d"|awk '$1~/^d/{i=0} $1~/^l/{i=1} $1~/^-/{i=2} NF>2{print i OFS $0}' | sort -n -k1,1 | cut -d ' ' -f2- done } 
+4
source share
3 answers

Continued answer from @chepner:

Instead of working ls several times with grep , I think that it can be combined into one command with awk, sort, cut and get the same output (first directories, then files, then links):

 function ll () { for d in " $@ "; do ls -lh --color "$d"|awk '$1~/^d/{i=0} $1~/^l/{i=1} $1~/^-/{i=2} NF>2{print i OFS $0}'|sort -n -k1,1|cut -d ' ' -f2- done } 
+3
source

Handle each ll argument separately:

 function ll () { for d in " $@ "; do ls -lh --color "$d" | grep "^d"; ls -lh --color "$d" | grep "^-" | grep -v "~"; ls -lh --color "$d" | grep "^l" done } 
+5
source

Try this option:

 function ll { local FILES=() OPTIONS=() A while [[ $# -gt 0 ]]; do case "$1" in --) FILES+=("${@:2}") break ;; -*) OPTIONS+=("$1") ;; *) FILES+=("$1") ;; esac shift done local -i FILES_COUNT=${#FILES[@]} I for (( I = 0; I < FILES_COUNT; ++I )); do A=${FILES[I]} [[ I -gt 0 ]] && echo [[ FILES_COUNT -gt 1 && -d $A/. ]] && echo "${A}:" # ls -lh --color "${OPTIONS[@]}" -- "$A" | grep "^total " ls -lh --color "${OPTIONS[@]}" -- "$A" | grep "^d"; ls -lh --color "${OPTIONS[@]}" -- "$A" | grep "^-" | grep -v "~"; ls -lh --color "${OPTIONS[@]}" -- "$A" | grep "^l" done } 

It somehow tries to separate directories when multiple arguments are passed in a manner similar to ls behavior. And it will also filter the added options.

+1
source

Source: https://habr.com/ru/post/1499403/


All Articles