The -U
option for ls
is not in POSIX, and in OS X's ls
it has a different meaning from GNU ls
, which is that it makes -t
and -l
use creation times instead of modification times. -f
is in POSIX as an XSI extension. The manual of GNU ls
describes -f
as do not sort, enable -aU, disable -ls --color
and -U
as do not sort; list entries in directory order
.
POSIX describes -f
like this:
Force each argument to be interpreted as a directory and list the name found in each slot. This option shall turn off -l
, -t
, -s
, and -r
, and shall turn on -a
; the order is the order in which entries appear in the directory.
Commands like ls|wc -l
give the wrong result when filenames contain newlines.
In zsh you can do something like this:
a=(*(DN));echo ${#a}
D
(glob_dots
) includes files whose name starts with a period and N
(null_glob
) causes the command to not result in an error in an empty directory.
Or the same in bash:
shopt -s dotglob nullglob;a=(*);echo ${#a[@]}
If IFS
contains ASCII digits, add double quotes around ${#a[@]}
. Add shopt -u failglob
to ensure that failglob
is unset.
A portable option is to use find
:
find . ! -name . -prune|grep -c /
grep -c /
can be replaced with wc -l
if filenames do not contain newlines. ! -name . -prune
is a portable alternative to -mindepth 1 -maxdepth 1
.
Or here's another alternative that does not usually include files whose name starts with a period:
set -- *;[ -e "$1" ]&&echo "$#"
The command above does however include files whose name starts with a period when an option like dotglob
in bash or glob_dots
in zsh is set. When *
matches no file, the command results in an error in zsh with the default settings.