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