#file-listing #file-path #show #directory #command-line #month #file-extension

bin+lib ex-cli

Command line tool to find, filter, sort and list files

12 stable releases

1.12.0 Feb 28, 2025
1.11.0 Nov 3, 2024
1.10.0 Aug 31, 2024
1.9.0 Jul 27, 2024
1.3.0 Nov 24, 2023

#185 in Filesystem

Download history 2/week @ 2024-11-13 9/week @ 2024-12-04 16/week @ 2024-12-11 6/week @ 2025-02-05 60/week @ 2025-02-12 155/week @ 2025-02-26

221 downloads per month

GPL-3.0-or-later

440KB
9K SLoC

Ex Directory Listing Tool

Versions

Version Released Change
1.0.0 09-Oct-2023 Initial version.
1.1.0 24-Oct-2023 Case insensitive match on Windows.
Show links as absolute paths.
Show links with file or directory colour.
Use LS_COLORS variable in Bash.
Accept multiple -t options.
1.2.0 05-Nov-2023 Find relative links from subdirectories.
Show bad links with zero size and time.
Include executable files with -tf option.
1.3.0 24-Nov-2023 Order by directory with -od option.
Show file depth with --debug option.
Miscellaneous bug fixes with -i option.
1.4.0 03-Jan-2024 Make command completion work.
1.5.0 25-Apr-2024 Pretty print file sizes and times.
Optionally recurse into hidden directories with -aa option.
1.6.0 25-May-2024 Correct parent directory indentation with -i option.
1.7.0 17-Jun-2024 Find recent files by local time not UTC.
Use box drawing characters for indentation with -i option.
Add trailing slash or backslash to links to directories.
No longer show file depth with --debug option.
1.8.0 29-Jun-2024 Force case sensitive match on Windows with --case option.
Force case insensitive match on Linux with --no-case option.
Use hyphenated long option names.
1.9.0 27-Jul-2024 Show file times in UTC with --utc option.
Show file versions on Windows with --win-ver option.
1.10.0 31-Aug-2024 Show files in hidden parent directories with -a option.
Show files in darker colour on Linux if not executable by current user or group.
Show owner information (user and group) on Linux with --owner option.
1.11.0 03-Nov-2024 Optionally filter executables on Linux with -te option.
1.12.0 28-Feb-2025 Expand compressed files with -z option.
Show owner on parents with -si option.
Show file extensions as lower case.
Show file depth with --debug option (debug builds only).
Show offending path on file system errors.

Introduction

Ex is a command line tool for listing directory contents. As such, it is intended as a replacement for:

  • The ls command in Bash (but easier to use).
  • The find command in Bash (but easier to use).
  • The dir command on Windows (but with more features and nicer output).

It is designed to work with POSIX shell command pipelines. For example:

  • If writing to a console, all attributes are shown.
  • If writing to a pipe or file, attributes are hidden, and filenames are escaped.

By default, it finds files in the current directory, and lists them with file type (d for directories, l for links, - for regular files) and permissions (r for readable, w for writable, x for executable, for owner, group and other) followed by size, age and extension. Directories are also indicated by a trailing path separator:

~/example $ ex
drwxr-xr-x    0 B    1 day          files/
-rwxr--r--   10 B    2 month  .sh   find.sh

Feature requests are welcome, but it's a hobby project in a language I don't get to use in my day job, so I prefer to do all the development myself.

Features

Colour Output by File Type

Unless piped to a command or file, Ex uses coloured output according to environment variable LS_COLORS, defined in Bash:

  • If LS_COLORS is present, uses the defined colours for image and video files (magenta by default), music files (cyan) and compressed files (red) by file extension.
  • If LS_COLORS is present, uses the defined colours for directories (blue by default), executable files (green), resolved links (cyan) and unresolved links (red on black).
  • If LS_COLORS is missing, hard codes the colours listed above for directories, executable files and symbolic links.
  • Additionally on Linux, uses the dark version of the executable colour for files which are executable for a different user or group.

Find Files in Subdirectories

If Ex is run with option -s or --recurse, it finds files in subdirectories. If run with option -d or --depth, it finds files between minimum and maximum depth, where depth 0 corresponds to the current directory:

  • Use -s to find files in subdirectories.
  • Use -d4 or -d-4 to find files up to depth 4.
  • Use -d2-4 to find files at depth 2, 3 or 4.
  • Use -d2- to find files at depth 2 and beyond.

It uses path separator / in Bash, including Git Bash on Windows:

~/example $ ex -s
-rwxr--r--   10 B    2 month  .sh   find.sh
drwxr-xr-x    0 B    1 day          files/
drwxr-xr-x    0 B    1 day          files/colours/
-rwxr--r--   20 B    3 month  .sh   files/colours/alpha.sh
-rw-r--r--   30 B    4 month  .txt  files/colours/blue.txt
-rw-r--r--   40 B    5 month  .txt  files/colours/green.txt
-rw-r--r--   50 B    6 month  .txt  files/colours/red.txt
drwxr-xr-x    0 B    1 day          files/numbers/
lrwxr--r--   60 B    7 month  .sh   files/numbers/count.sh -> /home/username/numbers/count.sh
lrw-r--r--  999 KB   8 month  .gz   files/numbers/googolplex.gz -> /home/username/numbers/googolplex.gz
lrw-r--r--    0 B    9 month        files/numbers/ordinals -> /home/username/numbers/ordinals/
drwxr-xr-x    0 B    1 day          files/numbers/one two/
-rw-r--r--   70 B   10 month  .txt  files/numbers/one two/"three" 'four'.txt

It uses path separator \\ on Windows:

C:\Users\username\example> ex.exe -s
-rwxrwxrwx   10 B    2 month  .sh   find.sh
drwxrwxrwx    0 B    1 day          files\
drwxrwxrwx    0 B    1 day          files\colours\
-rwxrwxrwx   20 B    3 month  .sh   files\colours\alpha.sh
-rw-rw-rw-   30 B    4 month  .txt  files\colours\blue.txt
-rw-rw-rw-   40 B    5 month  .txt  files\colours\green.txt
-rw-rw-rw-   50 B    6 month  .txt  files\colours\red.txt
drwxrwxrwx    0 B    1 day          files\numbers\
lrwxrwxrwx   60 B    7 month  .sh   files\numbers\count.sh -> C:\Users\username\numbers\count.sh
lrw-rw-rw-  999 KB   8 month  .gz   files\numbers\googolplex.gz -> C:\Users\username\numbers\googolplex.gz
lrw-rw-rw-    0 B    9 month        files\numbers\ordinals -> C:\Users\username\numbers\ordinals\
drwxrwxrwx    0 B    1 day          files\numbers\one two\
-rw-rw-rw-   70 B   10 month  .txt  files\numbers\one two\"three" 'four'.txt

It accepts wildcards like *.txt, with shortcuts like .txt for ease of typing:

~/example $ ex -s .txt
-rw-r--r--   30 B    4 month  .txt  files/colours/blue.txt
-rw-r--r--   40 B    5 month  .txt  files/colours/green.txt
-rw-r--r--   50 B    6 month  .txt  files/colours/red.txt
-rw-r--r--   70 B   10 month  .txt  files/numbers/one two/"three" 'four'.txt

If given directories with a trailing separator, it lists the contents of the directories; otherwise, it lists the directories themselves:

~/example $ ex files/colours
drwxr-xr-x    0 B    1 day    files/colours/
~/example $ ex files/colours/
-rwxr--r--   20 B    3 month  .sh   files/colours/alpha.sh
-rw-r--r--   30 B    4 month  .txt  files/colours/blue.txt
-rw-r--r--   40 B    5 month  .txt  files/colours/green.txt
-rw-r--r--   50 B    6 month  .txt  files/colours/red.txt

Indent Files in Subdirectories

If Ex is run with option -i or --indent, it indents files in subdirectories:

~/example $ ex -si
-rwxr--r--   10 B    2 month  .sh   find.sh
drwxr-xr-x    0 B    1 day          files
drwxr-xr-x    0 B    1 day           ├─ colours
-rwxr--r--   20 B    3 month  .sh    │   ├─ alpha.sh
-rw-r--r--   30 B    4 month  .txt   │   ├─ blue.txt
-rw-r--r--   40 B    5 month  .txt   │   ├─ green.txt
-rw-r--r--   50 B    6 month  .txt   │   └─ red.txt
drwxr-xr-x    0 B    1 day           └─ numbers
lrwxr--r--   60 B    7 month  .sh        ├─ count.sh -> /home/username/numbers/count.sh
lrw-r--r--  999 KB   8 month  .gz        ├─ googolplex.gz -> /home/username/numbers/googolplex.gz
lrw-r--r--    0 B    9 month             ├─ ordinals -> /home/username/numbers/ordinals/
drwxr-xr-x    0 B    1 day               └─ one two
-rw-r--r--   70 B   10 month  .txt           └─ "three" 'four'.txt

Show Hidden Files and Directories

By default, Ex hides:

  • Hidden files like .bashrc.
  • Hidden directories like .git.
  • Python cache directories __pycache__.

If run with option -a or --all-files, it shows hidden files and directories:

~/example $ ex -d1 -a
-rwxr--r--   10 B    2 month  .sh   find.sh
drwxr-xr-x    0 B    1 day          .hidden/
drwxr-xr-x    0 B    1 day          files/
drwxr-xr-x    0 B    1 day          files/colours/
drwxr-xr-x    0 B    1 day          files/numbers/

If run with repeated option -aa, it also recurses into hidden directories:

~/example $ ex -d1 -aa
-rwxr--r--   10 B    2 month  .sh   find.sh
drwxr-xr-x    0 B    1 day          .hidden/
-rwxr--r--   15 B    1 day    .dat  .hidden/password.dat
-rwxr--r--   15 B    1 day    .dat  .hidden/secret.dat
drwxr-xr-x    0 B    1 day          files/
drwxr-xr-x    0 B    1 day          files/colours/
drwxr-xr-x    0 B    1 day          files/numbers/

Show Contents of Compressed Files

If run with option -z or --zip, Ex expands *.zip, *.7z, *.tar and *.tar.gz compressed files. All other filtering and sorting options work as if the compressed files were directories:

~/zipped $ ex -s
-rw-r--r--  160 B    1 year   .7z   backup.7z
-rw-r--r--   10 KB   1 year   .tar  backup.tar
-rw-r--r--  234 B    1 year   .gz   backup.tar.gz
-rw-r--r--  120 B    1 year   .zip  backup.zip
drwxr-xr-x    0 B    1 day          backup/
-rw-rw-r--  100 B    1 year   .txt  backup/file.txt
~/zipped $ ex -sz
drwxr-xr-x    0 B    1 day          backup/
-rw-rw-r--  100 B    1 year   .txt  backup/file.txt
drw-r--r--    0 B    1 year         backup.7z/
----------  100 B    1 year   .txt  backup.7z/file.txt
drw-r--r--    0 B    1 year         backup.tar/
-rw-rw-r--  100 B    1 year   .txt  backup.tar/file.txt
drw-r--r--    0 B    1 year         backup.tar.gz/
-rw-rw-r--  100 B    1 year   .txt  backup.tar.gz/file.txt
drw-r--r--    0 B    1 year         backup.zip/
-rw-rw-r--  100 B    1 year   .txt  backup.zip/file.txt
~/zipped $ ex -sz backup.zip
-rw-rw-r--  100 B    1 year   .txt  backup.zip/file.txt

Match Case Sensitive Filenames

By default, Ex uses case sensitive filename matching on Linux, and case insensitive matching on Windows (including Git Bash) to match the file system. If run with option --case or --no-case, it overrides this behaviour.

Sort Files by Natural Ordering

By default, Ex uses natural ordering on filenames:

~/ordered $ ex
-rw-rw-r--    0 B    1 year   .txt  file8.txt
-rw-rw-r--    0 B    1 year   .txt  file9.txt
-rw-rw-r--    0 B    1 year   .txt  file10.txt
-rw-rw-r--    0 B    1 year   .txt  file11.txt
-rw-rw-r--    0 B    1 year   .txt  file98.txt
-rw-rw-r--    0 B    1 year   .txt  file99.txt
-rw-rw-r--    0 B    1 year   .txt  file100.txt
-rw-rw-r--    0 B    1 year   .txt  file101.txt

Sort Files by Attribute

By default, Ex shows directories before files in the current directory, groups directories and their children if recursing, and sorts by filename within those groups. If run with option -o or --order, it sorts files and directories according to the option:

  • Use -on to sort files by filename.
  • Use -oe to sort files by extension.
  • Use -os to sort files by size (increasing).
  • Use -os- to sort files by size (decreasing).
  • Use -ot to sort files by time (increasing).
  • Use -ot- to sort files by time (decreasing).
  • Use -oest to sort files by extension then size then time.

For example:

~/example $ ex -d2 -oes
drwxr-xr-x    0 B    1 day          files/
drwxr-xr-x    0 B    1 day          files/colours/
drwxr-xr-x    0 B    1 day          files/numbers/
lrw-r--r--    0 B    9 month        files/numbers/ordinals -> /home/username/numbers/ordinals/
drwxr-xr-x    0 B    1 day          files/numbers/one two/
lrw-r--r--  999 KB   8 month  .gz   files/numbers/googolplex.gz -> /home/username/numbers/googolplex.gz
-rwxr--r--   10 B    2 month  .sh   find.sh
-rwxr--r--   20 B    3 month  .sh   files/colours/alpha.sh
lrwxr--r--   60 B    7 month  .sh   files/numbers/count.sh -> /home/username/numbers/count.sh
-rw-r--r--   30 B    4 month  .txt  files/colours/blue.txt
-rw-r--r--   40 B    5 month  .txt  files/colours/green.txt
-rw-r--r--   50 B    6 month  .txt  files/colours/red.txt

Sort Files by Name

If Ex is run with option -on, it additionally shows directories in parentheses:

~/example $ ex -s -on .sh
-rwxr--r--   20 B    3 month  .sh   alpha.sh (files/colours/)
lrwxr--r--   60 B    7 month  .sh   count.sh (files/numbers/) -> /home/username/numbers/count.sh
-rwxr--r--   10 B    2 month  .sh   find.sh

Filter Files by Time

By default, Ex shows files and directories regardless of age. If run with option -r or --recent, it filters by modified time:

  • Use -rh to include files up to one hour old.
  • Use -rd to include files up to one day old.
  • Use -rw2 to include files up to two weeks old.
  • Use -rm6 to include files up to six months old.
  • Use -ry10 to include files up to ten years old.

For example:

~/example $ ex -s -rm5
Start                5 month
----------------------------
-rwxr--r--   10 B    2 month  .sh   find.sh
drwxr-xr-x    0 B    1 day          files/
drwxr-xr-x    0 B    1 day          files/colours/
-rwxr--r--   20 B    3 month  .sh   files/colours/alpha.sh
-rw-r--r--   30 B    4 month  .txt  files/colours/blue.txt
-rw-r--r--   40 B    5 month  .txt  files/colours/green.txt
drwxr-xr-x    0 B    1 day          files/numbers/
drwxr-xr-x    0 B    1 day          files/numbers/one two/

Filter Files by Type

By default, Ex shows files and directories regardless of type. If run with option -t or --type, it filters by type:

  • Use -tf to include files.
  • Use -te to include executables.
  • Use -td to include directories.
  • Use -tl to include links.

For example:

~/example $ ex -s -td
drwxr-xr-x    0 B    1 day    files/
drwxr-xr-x    0 B    1 day    files/colours/
drwxr-xr-x    0 B    1 day    files/numbers/
drwxr-xr-x    0 B    1 day    files/numbers/one two/
~/example $ ex -s -tfl
-rwxr--r--   10 B    2 month  .sh   find.sh
-rwxr--r--   20 B    3 month  .sh   files/colours/alpha.sh
-rw-r--r--   30 B    4 month  .txt  files/colours/blue.txt
-rw-r--r--   40 B    5 month  .txt  files/colours/green.txt
-rw-r--r--   50 B    6 month  .txt  files/colours/red.txt
lrwxr--r--   60 B    7 month  .sh   files/numbers/count.sh -> /home/username/numbers/count.sh
lrw-r--r--  999 KB   8 month  .gz   files/numbers/googolplex.gz -> /home/username/numbers/googolplex.gz
lrw-r--r--    0 B    9 month        files/numbers/ordinals -> /home/username/numbers/ordinals/
-rw-r--r--   70 B   10 month  .txt  files/numbers/one two/"three" 'four'.txt

Show Total Size

If Ex is run with option --total, it also shows the total file size, and number of files and directories:

~/example $ ex --total files/numbers/
drwxr-xr-x    0 B    1 day          files/numbers/one two/
lrwxr--r--   60 B    7 month  .sh   files/numbers/count.sh -> /home/username/numbers/count.sh
lrw-r--r--  999 KB   8 month  .gz   files/numbers/googolplex.gz -> /home/username/numbers/googolplex.gz
lrw-r--r--    0 B    9 month        files/numbers/ordinals -> /home/username/numbers/ordinals/
----------------------------
Total         1 MB                  3 files 1 directory

Show File Owner

If run with option --owner on Linux, Ex shows the owning user and group, like ls -l:

~/example $ ex -s --owner .sh
-rwxr--r--  root     root       10 B    2 month  .sh   find.sh
-rwxr--r--  username username   20 B    3 month  .sh   files/colours/alpha.sh
lrwxr--r--  username username   60 B    7 month  .sh   files/numbers/count.sh -> /home/username/numbers/count.sh

Show Only Paths

By default, Ex shows all file attributes (unless writing to a pipe or file) with file size and time pretty printing. If run with option -x or --only-path, it shows directories and filenames only:

~/example $ ex -sx
find.sh
files/
files/colours/
files/colours/alpha.sh
files/colours/blue.txt
files/colours/green.txt
files/colours/red.txt
files/numbers/
files/numbers/count.sh -> /home/username/numbers/count.sh
files/numbers/googolplex.gz -> /home/username/numbers/googolplex.gz
files/numbers/ordinals -> /home/username/numbers/ordinals/
files/numbers/one two/
files/numbers/one two/"three" 'four'.txt

If run with repeated option -xx, it shows all file attributes (even if writing to a pipe or file) and disables file size and time pretty printing, showing time in the local time zone:

~/example $ ex -sxx
-rwxr--r--       10  01-Nov-2024 00:00:00  .sh   find.sh
drwxr-xr-x        0  31-Dec-2024 00:00:00        files/
drwxr-xr-x        0  31-Dec-2024 00:00:00        files/colours/
-rwxr--r--       20  01-Oct-2024 00:00:00  .sh   files/colours/alpha.sh
-rw-r--r--       30  01-Sep-2024 00:00:00  .txt  files/colours/blue.txt
-rw-r--r--       40  01-Aug-2024 00:00:00  .txt  files/colours/green.txt
-rw-r--r--       50  01-Jul-2024 00:00:00  .txt  files/colours/red.txt
drwxr-xr-x        0  31-Dec-2024 00:00:00        files/numbers/
lrwxr--r--       60  01-Jun-2024 00:00:00  .sh   files/numbers/count.sh -> /home/username/numbers/count.sh
lrw-r--r--  999,999  01-May-2024 00:00:00  .gz   files/numbers/googolplex.gz -> /home/username/numbers/googolplex.gz
lrw-r--r--        0  01-Apr-2024 00:00:00        files/numbers/ordinals -> /home/username/numbers/ordinals/
drwxr-xr-x        0  31-Dec-2024 00:00:00        files/numbers/one two/
-rw-r--r--       70  01-Mar-2024 00:00:00  .txt  files/numbers/one two/"three" 'four'.txt

If run with repeated option -xx and option -u or --utc, it additionally shows file times in UTC:

~/example $ ex -sxxu
-rwxr--r--       10  01-Nov-2024 00:00:00Z  .sh   find.sh
drwxr-xr-x        0  31-Dec-2024 00:00:00Z        files/
drwxr-xr-x        0  31-Dec-2024 00:00:00Z        files/colours/
-rwxr--r--       20  30-Sep-2024 23:00:00Z  .sh   files/colours/alpha.sh
-rw-r--r--       30  31-Aug-2024 23:00:00Z  .txt  files/colours/blue.txt
-rw-r--r--       40  31-Jul-2024 23:00:00Z  .txt  files/colours/green.txt
-rw-r--r--       50  30-Jun-2024 23:00:00Z  .txt  files/colours/red.txt
drwxr-xr-x        0  31-Dec-2024 00:00:00Z        files/numbers/
lrwxr--r--       60  31-May-2024 23:00:00Z  .sh   files/numbers/count.sh -> /home/username/numbers/count.sh
lrw-r--r--  999,999  30-Apr-2024 23:00:00Z  .gz   files/numbers/googolplex.gz -> /home/username/numbers/googolplex.gz
lrw-r--r--        0  31-Mar-2024 23:00:00Z        files/numbers/ordinals -> /home/username/numbers/ordinals/
drwxr-xr-x        0  31-Dec-2024 00:00:00Z        files/numbers/one two/
-rw-r--r--       70  01-Mar-2024 00:00:00Z  .txt  files/numbers/one two/"three" 'four'.txt

Show Absolute Paths

By default, Ex shows relative paths (unless supplied absolute paths on the command line). If run with option -q or --abs-path, it shows absolute paths:

~/example $ ex -sq .txt
-rw-r--r--   30 B    4 month  .txt  /home/username/example/files/colours/blue.txt
-rw-r--r--   40 B    5 month  .txt  /home/username/example/files/colours/green.txt
-rw-r--r--   50 B    6 month  .txt  /home/username/example/files/colours/red.txt
-rw-r--r--   70 B   10 month  .txt  /home/username/example/files/numbers/one two/"three" 'four'.txt

Show Windows Paths

By default, Ex shows directories with path separator / in Git Bash on Windows, converting D:\Path to /d/Path; but sometimes it is necessary to generate Windows paths for copying and pasting into other programs. If run with option -w or --win-path, it does this:

~/example $ ex -sqw .txt
-rw-rw-rw-   30 B    4 month  .txt  C:\Users\username\example\files\colours\blue.txt
-rw-rw-rw-   40 B    5 month  .txt  C:\Users\username\example\files\colours\green.txt
-rw-rw-rw-   50 B    6 month  .txt  C:\Users\username\example\files\colours\red.txt
-rw-rw-rw-   70 B   10 month  .txt  C:\Users\username\example\files\numbers\one two\"three" 'four'.txt

Show Windows Versions

If run with option -v or --win-ver on Windows, Ex shows file versions for executable and DLL files:

C:\Users\username\bin> ex.exe -v
-rwxrwxrwx  123 KB   1 month  2.1.0.999   .exe  binary.exe
-rw-rw-rw-   45 KB   1 month  2.1.0.1001  .dll  library.dll
-rw-rw-rw-  678 B    1 month              .txt  README.txt

Support Shell Command Pipelines

If piped to a command or file, Ex hides attributes and escapes filenames:

~/example $ ex -s .txt | cat
files/colours/blue.txt
files/colours/green.txt
files/colours/red.txt
files/numbers/one\ two/\"three\"\ \'four\'.txt

If run with option --null-path, it uses a null character as a separator:

~/example $ ex -sz .txt | xargs -0 touch

Support Command Line Completion

If Ex is run with option --completion=bash, it generates a Bash completion script, and can be called from a .bashrc file:

source <(/home/username/bin/ex --completion=bash)

If Ex is run with option --completion=ps, it generates a PowerShell completion script, and can be called from a PowerShell $PROFILE file:

C:\Users\username\bin\ex.exe --completion=ps | Out-String | Invoke-Expression

Dependencies

~14–26MB
~396K SLoC