There is no need for ls, sed, wc or awk.
If you simply want to count how many names a pattern expands to, then you can do that with
set -- *
echo "$#"
The set command sets the positional parameters ($1, $2, etc.) to the names matching the * pattern. This automatically sets the special variable $# to the number of set positional parameters, i.e. the number of names matching the given pattern.
In bash or in a shell that has named arrays, you can use
names=(*)
echo "${#names[@]}"
This works similarly, but sets the elements of the names array to the names resulting from the expansion of the * pattern. The variable expansion ${#names[@]} will be the number of elements in the names array.
An issue with this is that if the pattern doesn't match anything, it will remain unexpanded, so you get a count of 1 (even though the directory is empty). To fix this in the bash shell, set the nullglob shell option with shopt -s nullglob. By setting this shell option, patterns that do not match anything will be removed completely.
In bash, if you additionally want to count hidden names, set the dotglob shell option with shopt -s dotglob.
Your function could look something like this in bash:
lsc () (
shopt -s nullglob
set -- "$1"/*
echo "$#"
)
Note the use of ( ... ) for the function body to avoid setting nullglob in the calling shell.
Or, for /bin/sh:
lsc () {
set -- "$1"/*
if [ -e "$1" ] || [ -L "$1" ]; then
echo "$#"
else
echo 0
fi
}
The if statement here makes sure that the first positional parameter is the name of an actual file and not an unexpanded pattern (due to not matching anything). The -e ("exists") must be true for us to trust the number in $#. If it isn't true, then we additionally check whether the name refers to a symbolic link with the -L test. If this is true, we know that the first thing that the pattern expanded to was a "dead" symbolic link (a symbolic link pointing to a non-existent file), and we trust $# to be correct. If both tests fail, we know that we didn't match anything and therefore output 0.
ls -1 | wc -l(that's a number 1 rather than a letter l) ? Or if keen on usingawk, you could usels -l | awk 'NR>1{a++}END{print a}'– steve Dec 27 '20 at 10:21ls -l | awk 'END{print NR-1}'works too. – steve Dec 27 '20 at 10:28touch $'file\n1' $'file\n2'and test it. – Kusalananda Dec 27 '20 at 11:49logrotatetried to handle such a file. Not writing your code to account for all possible file name characters is just asking for trouble. – Ed Morton Dec 27 '20 at 22:25\nin file names, for what usage ? – ychaouche Dec 28 '20 at 10:44/because directory paths are/-separated. There's simply no reason to disallow any other characters, people just have to write their code correctly and, as @kusalananda mentioned, it's easy to do so. – Ed Morton Dec 28 '20 at 17:30