user4556274 já respondeu o porquê . Minha resposta serve apenas para fornecer informações adicionais sobre como contar corretamente os arquivos.
Na comunidade Unix, o consenso geral é que analisar a saída de ls
é uma péssima idéia , já que os nomes de arquivos podem conter caracteres de controle ou caracteres ocultos. Por exemplo, devido a um caractere de nova linha em um nome de arquivo, ls | wc -l
informamos que há 5 linhas na saída de ls
(que possui), mas, na realidade, existem apenas 4 arquivos no diretório.
$> touch FILE$'\n'NAME
$> ls
file1.txt file2.txt file3.txt FILE?NAME
$> ls | wc -l
5
Método # 1: encontrar utilitário
O find
comando, normalmente usado para solucionar nomes de arquivos de análise, pode nos ajudar aqui imprimindo o número do inode . Seja um diretório ou um arquivo, ele possui apenas um número de inode exclusivo. Assim, usando -printf "%i\n"
e excluindo .
via -not -name "."
, podemos ter uma contagem precisa dos arquivos. (Observe o uso de -maxdepth 1
para impedir a descida recursiva em subdiretórios)
$> find -maxdepth 1 -not -name "." -print
./file2.txt
./file1.txt
./FILE?NAME
./file3.txt
$> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l
4
Método # 2: globstar
Maneira simples, rápida e principalmente portátil:
$ set -- *
$ echo $#
228
set
O comando é usado para definir parâmetros posicionais do shell (as $<INTEGER>
variáveis, como em echo $1
). Isso geralmente é usado para solucionar as /bin/sh
limitações de matrizes ausentes. Uma versão que realiza verificações extras pode ser encontrada na resposta de Gille no Unix e Linux.
Em shells que suportam matrizes, como bash
, podemos usar
items=( dir/* )
echo ${#items[@]}
como proposto por steeldriver nos comentários .
Truque semelhante ao find
método usado wc
e globstar pode ser usado stat
para contar números de inodes por linha:
$> LC_ALL=C stat ./* --printf "%i\n" | wc -l
4
Uma abordagem alternativa é usar um curinga no for
loop. (Observe, esse teste usa um diretório diferente para testar se essa abordagem é dividida em subdiretórios, o que não ocorre - 16 é o número verificado de itens no meu ~/bin
)
$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1
16
Método # 3: outros idiomas / intérpretes
O Python também pode lidar com nomes de arquivos problemáticos, imprimindo o tamanho de uma lista, de acordo com minha os.listdir()
função (que não é recursiva, e listará apenas os itens no diretório como argumento).
$> python -c "import os ; print os.listdir('.')"
['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt']
$> python -c "import os ; print(len(os.listdir('.')))"
4
Veja também
ls | wc -l
falhará se houver arquivos com uma nova linha no nome do arquivo. Isso é mais resiliente:find . -mindepth 1 -maxdepth 1 -printf . | wc -c