0

I have written the script below but it returns 0 for the number of files in the directory now matter how many files are in the directory.

source ~/Alan/assign/changeDir.sh
num=$(( ls | wc -l ))
echo $num

changeDir.sh script is the following

function my_cd() {
cd ~/Alan
}

All I need is a number to be returned in order for it to be used later in the same script. I would very much appreciate guidance on this. Thanks

AdminBee
  • 22,803
Alan N
  • 1

3 Answers3

3

To find the number of names in a single directory, expand the * glob in it and count the number of generated words:

shopt -s nullglob    # to make the * glob expand to nothing
                     # if there is no matching names
set -- *
num=$#

printf '%s\n' "$num"

The special value $# is the number of positional parameters. The set command sets the positional parameters.

Would you want to count regular files only, and include hidden names, then use

shopt -s nullglob dotglob

for name in *; do
    if [ ! -f "$name" ] || [ -L "$name" ]; then
        # skip non-regular files and symbolic links
        continue
    fi
    files+=( "$name" )
done

num=${#files[@]}

printf '%s\n' "$num"

To do that recursively into subdirectories, also set the globstar shell option and use **/* as the globbing pattern.

(in the zsh shell, it would be enough with set -- **/*(.DN); print $#)

The issue with your

num=$(( ls | wc -l ))

is twofold:

  1. $(( ... )) is an arithmetic expansion. You probably want a command substitution here, $( ... ).
  2. The wc -l will not count files. It will count the number of newline characters outputted by ls. A file with one or more newlines in its name will be counted as multiple files by wc -l. You can test this by creating such a file using touch $'hello\nworld'.
Kusalananda
  • 333,661
2

If you want to count files including hidden files (.*) , but have subdirectories excluded, you can use:

find . -maxdepth 1 -type f -printf '.' | wc -c

All benefits of find may be used.

pLumo
  • 22,565
0

I think the problem is a wrong syntax in your command substitution.

The command

num=$(( expression ))

will interpret the content of the parentheses as an arithmetic expression and assign the numerical result to num. It will not return the output of running that which is written inside the parentheses as code. Rather, ls, wc and l will be interpreted as shell variables, and the operation "$ls OR $wc minus $l" be performed, which results in zero as none of these "variables" are initialized.

What you are probably trying to do would be written as

num="$(ls | wc -l)"

However, even so, parsing the output of ls is not a good idea in general. Rather, look at some of the answers to this similar question where "robust" solutions are presented that will also work when filenames contain special characters.

AdminBee
  • 22,803