clf, cls: "Compressed" ls Listings

Most newer UNIX systems let you make filenames that are hundreds of characters long. The bad thing about that is that when ls lists the filenames in columns, it can't fit many columns across the screen. If your directory has a lot of files, the listing can scroll off the screen.

I wrote a script that lists a directory in five columns. If a filename doesn't fit, the script truncates the name and prints a right angle bracket (>) at the end of the name. Here's a demo. It starts with the standard ls and its -F option () to mark directories with a trailing / and executable files with a *. Next, clf gives the same listing, compressed. Third, cls gives a listing without the / and *.

% ls -F HOMEDIR_backup/ more* adir/ projects.1995/ afile projects.1996/ cfile updatedb.client dfile zfile file_with_a_very_long_name_what_a_mess* zoo.tar.Z jerryp_MH.tar.Z % clf HOMEDIR_back>/ cfile jerryp_MH.tar> projects.1996/ zoo.tar.Z adir/ dfile more* updatedb.clie> afile file_with_a_>* projects.1995/ zfile % cls HOMEDIR_backup cfile jerryp_MH.tar> projects.1996 zoo.tar.Z adir dfile more updatedb.clie> afile file_with_a_v> projects.1995 zfile


cls The script has a total of four names (links). cls lists in columns that are sorted top to bottom. clf is like cls, but marks directories and executable files. cls2 and clf2 are like cls and clf, but they sort filenames side to side instead; this is faster but may not be as easy to read. The script tests its name and does the right commands in a case statement () that starts like this:


case "$0" in *clf2) $ls -F ${1+"$@"} | sed -e "$sed" | $pr -l1; exit ;; ...

The ${1+"$@"} passes in quoted filenames from the command line without breaking them into pieces at the spaces. This is a workaround for differences in the way some old Bourne shellshandle an empty "$@" parameter . ()

The "guts" of the shell script is the two-line sed () command below (the single quotes around the expression pass both lines into the shell variable at once):

sed="/[/@*=]$/s/^\(............\)...*\([/@*=][/@*=]*\)$/\1>\2/ s/^\(.............\)...*/\1>/"

The ls output is piped to sed's standard input:

If you figured that out yourself, tell your manager that I think you deserve a promotion :-).

The other tricky part is this line:

`...` 
$pr -l`expr \( `wc -l < $temp` / 5 \) + 1` $temp

It's used when you call the script clf or cls and the filenames need to be printed down columns instead of across. The same kind of line is used in article - it's explained there. The time that line takes to run is why clf and cls are a little slower than clf2 and cls2.

You can install this script from the tutorial or from the online archive (). If you get it from the archive, ask tar to install cls and its three other links:

% tar xvf archive.tar cls clf cls2 clf2 x cls, 1282 bytes, 3 tape blocks clf linked to cols cls2 linked to cols clf2 linked to cols

- JP