Your command is nonsensical. First of all, cd /../..
is the same as cd /
, i.e. it will just change the current working directory to the top-most directory in the directory hierarchy. Secondly, cd
does not produce any output, so piping it to anything is not going to do much good.
Thirdly, ls -l
will produce a listing of entries (names) in the current directory. You are using wc -l
to count the number of lines in the output of ls -l
. This number likely be at least one more than the real number of directory entries in any directory since ls -l
outputs a sort of header (BSD ls
doesn't do this for empty directories, but GNU ls
always does). ls -l
will not list hidden filenames, and it will (when piped to wc -l
) produce multiple lines for files that have newlines embedded in their filenames.
Don't use ls
for anything other than for looking at directory listings (with your eyes), and only ever use wc -l
to count lines. There are smarter and quicker ways to count files.
Related:
To list the number of directory entries (names) inside all 2nd level subdirectories using bash
, use something like
shopt -s nullglob dotglob
for dirpath in /*/*/; do
set -- "$dirpath"/*
printf '%d\t%s\n' "$#" "$dirpath"
done
This loops over all 2nd level directories. For each directory, it expands the *
globbing pattern in the directory and sets the positional parameters to the resulting names. After doing so, the special variable $#
will contain the number of positional parameters (names in the directory). We then print the directory pathname together with that count.
The nullglob
and dotglob
shell options are first set so that we correctly count hidden names and so that we get the correct count (0) for empty directories.
Would you want to have a recursive count of each subdirectory at level 2:
shopt -s nullglob dotglob globstar
for dirpath in /*/*/; do
set -- "$dirpath"/**/*
printf '%d\t%s\n' "$#" "$dirpath"
done
The globstar
shell option in bash
enables the use of **
, which is a pattern that matches "recursively" down into subdirectories.
Would you want to only list the ones with 20 or more entries in them (here using the second variation from above, which counts names recursively in each subdirectory):
shopt -s nullglob dotglob globstar
for dirpath in /*/*/; do
set -- "$dirpath"/**/*
if [[ $# -ge 20 ]]; then
printf '%d\t%s\n' "$#" "$dirpath"
fi
done
wc -l
never counts files. It only counts lines of text. If filenames contains newlines, these would be counted multiple times bywc -l
. – Kusalananda Oct 13 '19 at 19:16wc -l
does not count files. It counts lines. Try creating an empty directory, and then runtouch $'one\nfile'
inside it.ls -l | wc -l
will give you3
(2 for the file, and one for the header that it always outputs when using its long format output). – Kusalananda Oct 13 '19 at 19:24