The first way to simplify the script would be to save the number of files into a variable so that you don't have to recompute it.
Other ways to come up with the number of files in the current directory:
n=$(ls -l | grep -c ^-)
Here, the simplification is using grep's -c option to count the matches. There's a risk of miscounting the matches when parsing the output of ls if there is a file named $'some\n-file', which pretends to put a hyphen at the beginning of the line.
n=$(stat -c %F -- * | grep -c 'regular .*file')
The .* in the grep is to account for both "regular file" and "regular empty file" matches. The stat command outputs the type of each file, and the * shell glob avoids the concerns with ls.
If you're familiar with bash, but have heard of zsh and it's powerful filename globbing syntax, you could:
n=$(zsh -c 'a=( *(.) ); echo ${#a}')
Where we create an array named a that is populated with the list of files * filtered by only "plain files" with ..
To print the plural correctly, consider a case statement:
case $n in
(1) printf "1 file";;
(*) printf "$n files";;
esac
A case statement would allow more flexibility if you wanted to print different messages for different numbers of files, for example: "No files!".
More simply, consider a conditional:
[[ $n == 1 ]] && printf "1 file" || printf "$n files"
Finally getting around to steeldriver's suggestion:
n=$( files=(*); dirs=(*/); echo $(( ${#files[@]} - ${#dirs[@]} )))
printf "%d file%s" "$n" "$(test "$n" -ne 1 && echo s)"
This assigns a value to n (eventually) by opening a command substitution; inside that temporary command substitution, I create two arrays: files for everything and dirs for only directories. The last act of the command substitution is to report the difference between the two. The printf then prints the number of files along with the appropriate plural suffix.
This uses whatever setting you have for dotglob; if you want to force the counting (or omission) of dot-files, then you should set or unset dotglob inside the command substitution:
use the current value of dotglob:
n=$( files=(*); dirs=(*/); echo $(( ${#files[@]} - ${#dirs[@]} )))
enforce counting of dot-files, regardless of current dotglob:
n=$(shopt -s dotglob;
files=(*); dirs=(*/); echo $(( ${#files[@]} - ${#dirs[@]} )))
enforce no counting of dot-files, regardless of current dotglob:
n=$(shopt -u dotglob;
files=(*); dirs=(*/); echo $(( ${#files[@]} - ${#dirs[@]} )))