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 (16.12)
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 (44.6) 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 . (46.7)
The "guts" of the shell script is the two-line sed (34.24) 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:
The first sed script line matches lines that are more than 14
characters long and end with one of the symbols
*
, /
, @
, or =
.
The
"escaped parenthesis" operators
/(.../)
(34.10)
grab the first 12 characters into \1
and the symbol into
\2
-then print them both together with a >
between.
The second sed line matches other filenames over 14 characters
that don't end with a symbol.
(It won't match filenames that the first line
matched because the first line shortened them.)
The second line grabs the first 13 characters, prints them with a
>
on the end.
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 35.16- 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 CD-ROM or from the online archive (52.7). 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
-