Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Wrapper script for exa to give it nearly identical switches and appearance to ls. Also automatically adds --git switch when in a git repository.
## Change following to '0' for output to be like ls and '1' for exa features
# Don't list implied . and .. by default with -a
# Show human readable file sizes by default
# Don't show group column
# Don't show hardlinks column
# Group directories first in long listing by default
# Show file git status automatically (can cause a slight delay in large repo subdirectories)
help() {
cat << EOF
${0##*/} options:
-a all
-A almost all
-1 one file per line
-x list by lines, not columns
-l long listing format
-G display entries as a grid *
-k bytes
-h human readable file sizes
-F classify
-R recurse
-r reverse
-d don't list directory contents
-D directories only *
-M group directories first *
-I ignore [GLOBS]
-i show inodes
-N no colour *
-S sort by file size
-t sort by modified time
-u sort by accessed time
-U sort by created time *
-X sort by extension
-T tree *
-L level [DEPTH] *
-s file system blocks
-g don't show/show file git status *
-n ignore .gitignore files *
-@ extended attributes and sizes *
* not used in ls
[[ "$*" =~ --help ]] && help
while getopts ':aAtuUSI:rkhnsXL:MNg1lFGRdDiTx@' arg; do
case $arg in
a) (( dot == 1 )) && exa_opts+=(-a) || exa_opts+=(-a -a) ;;
A) exa_opts+=(-a) ;;
t) exa_opts+=(-s modified); ((++rev)) ;;
u) exa_opts+=(-us accessed); ((++rev)) ;;
U) exa_opts+=(-Us created); ((++rev)) ;;
S) exa_opts+=(-s size); ((++rev)) ;;
I) exa_opts+=(--ignore-glob="${OPTARG}") ;;
r) ((++rev)) ;;
k) ((--hru)) ;;
h) ((++hru)) ;;
n) exa_opts+=(--git-ignore) ;;
s) exa_opts+=(-S) ;;
X) exa_opts+=(-s extension) ;;
L) exa_opts+=(--level="${OPTARG}") ;;
M) ((++gpd)) ;;
N) ((++nco)) ;;
g) ((++git)) ;;
1|l|F|G|R|d|D|i|T|x|@) exa_opts+=(-"$arg") ;;
:) printf "%s: -%s switch requires a value\n" "${0##*/}" "${OPTARG}" >&2; exit 1
*) printf "Error: %s\n --help for help\n" "${0##*/}" >&2; exit 1
shift "$((OPTIND - 1))"
(( rev == 1 )) && exa_opts+=(-r)
(( hru <= 0 )) && exa_opts+=(-B)
(( fgp == 0 )) && exa_opts+=(-g)
(( lnk == 0 )) && exa_opts+=(-H)
(( nco == 1 )) && exa_opts+=(--color=never) || exa_opts+=(--color=always)
(( gpd >= 1 )) && exa_opts+=(--group-directories-first)
(( git == 1 )) && \
[[ $(git -C "${*:-.}" rev-parse --is-inside-work-tree) == true ]] 2>/dev/null && exa_opts+=(--git)
exa --color-scale "${exa_opts[@]}" "$@"
Copy link

tachoknight commented Apr 6, 2021

Hey, I made a modification to your script to change -h to -H for help; -h shows the size in human readable format (e.g. k for kilobytes). Thanks for writing this, it's really nice!

Copy link

tachoknight commented Apr 6, 2021

Also, I have too many years of ls to use exa so I compromised and put this script in $HOME/.local/bin renamed this to and did a ln -s lls and now muscle memory is basically there, I just have to type an additional "l". :)

Copy link

eggbean commented Apr 7, 2021

@tachoknight You can make an alias to replace ls by adding this to your ~/.bash_aliases file (assuming it is called and you are using bash):

if command -v exa >/dev/null; then
    alias ls=''
    alias ls='/bin/ls $LS_OPTIONS'

Copy link

tachoknight commented Apr 7, 2021

I considered making an alias but I have a number of jobs that make use of ls output with awk that would break, so I opted to leave ls as-is and go with something only I'd know. I'm also experimenting with ks as it's just one key over from l. Definitely need to work on the muscle memory!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment