Você provavelmente deseja usar apenas find
. Supondo que você não tenha arquivos com novas linhas em seus nomes, apenas algo assim faria:
find "$dir" -type f | wc -l
-type f
corresponde a arquivos regulares, mas não a diretórios, pipes, soquetes ou o que for.
A saída usual de find
separa os nomes de arquivos por novas linhas, portanto, se algum dos nomes contiver novas linhas, a saída será ambígua. Com o GNU find, algo assim funcionaria:
find "$dir" -type f -printf . | wc -c
Isso tem find
imprime apenas um ponto para cada arquivo e conta os pontos.
Outras versões do find
não têm -printf
, mas podemos usar o truque de passar o caminho de entrada com barras duplas. Eles são tratados como uma única barra, mas não aparecerão naturalmente na saída, pois os nomes de arquivos não podem conter barras. Em seguida, conte as barras duplas na saída:
find "$dir//" -type -f | grep -c //
Se quisermos fazer isso com puramente um script de shell, podemos ter o shell
listar os nomes de arquivo, não é necessário usar ls
, por exemplo no Bash:
#!/bin/bash
files=0
shopt -s dotglob
countfiles() {
local f;
for f in * ; do
if [ -f "$f" ] ; then # count regular files
files=$((files + 1))
elif [ -d "$f" ] ; then # recurse into directories
cd "$f"
countfiles
cd ..
fi
done
}
cd "$1"
countfiles
echo $files