Se assim for ls -1 target_dir | wc -l
, recebo uma contagem de arquivos em um diretório. Acho isso um pouco complicado. Existe uma maneira mais elegante ou sucinta?
ubuntu
command-line
filesystems
codecowboy
fonte
fonte
ls
já dá a contagem total, e daíls -l | head -1
? Crie um alias se você quiser algo mais curto.ls -l
indica o tamanho total dos arquivos, não o número de arquivos.ls | wc -l
você receberá a contagem errada se algum nome de arquivo contiver novas linhas.stat -c %h .
dá a mesma informação quels -ld . | cut -d" " -f 2
Respostas:
Supondo que o bash 4+ (que qualquer versão suportada do Ubuntu possui):
Chame como
num_files [dir]
.dir
é opcional, caso contrário, ele usa o diretório atual. Sua versão original não conta arquivos ocultos, nem isso. Se você quer isso,shopt -s dotglob
antesset -- *
.Seu exemplo original conta não apenas arquivos regulares, mas também diretórios e outros dispositivos - se você realmente deseja apenas arquivos regulares (incluindo links simbólicos para arquivos regulares), será necessário verificá-los:
Se você encontrar o GNU, algo como isso também é uma opção (observe que isso inclui arquivos ocultos, o que seu comando original não fez):
(mude
-type
para-xtype
se você também deseja contar links simbólicos para arquivos regulares).fonte
set
falhará se houver muitos arquivos? Eu acho que você pode ter que usarxargs
e algum código de soma para fazer isso funcionar no caso geral.shopt -s dotglob
, se você quiser arquivos começando com.
a ser contadoset
irá falhar nessas circunstâncias, já que não estamos fazendo umexec
. A saber, no meu sistema,getconf ARG_MAX
produz 262.144, mas se eu fizertest_arg_max() { set -- {1..262145}; echo $#; }; test_arg_max
, ele alegremente responde 262145.-maxdepth
não é POSIX.f=(target_dir/*);echo ${#f[*]}
funciona corretamente para arquivos com espaços, novas linhas etc. no nome.
fonte
ls
é multi-colunas somente se tiver saída direta para um terminal, você pode remover a opção "-1", você pode remover awc
opção "-l", ler apenas o primeiro valor (solução lenta, não deve ser usada para evidências legadas, investigações criminais, missões críticas, operações táticas ..).fonte
wc
para obter o número de arquivos, mesmo no caso trivial, então como isso é uma solução?target
for um globo que, quando expandido, inclui algumas coisas que começam com hífens. Por exemplo, fazer um novo diretório, entrar nele e nãotouch -- {1,2,3,-a}.txt && ls *|wc
: (NB usorm -- *.txt
para excluir esses arquivos.)wc -l
? Caso contrário, você obterá novas contagens de linhas, palavras e bytes dals
saída. Foi o que David Richerby disse: você precisa analisá-lo novamente.wc
sem argumento, que você não precisa analisar se seu cérebro sabe que o primeiro argumento é nova linha.Se você está buscando a sucessão (e não a exatidão exata ao lidar com arquivos com novas linhas em seus nomes, etc.), recomendo que você faça um alias
wc -l
paralc
("contagem de linhas"):Como outros observaram, você não precisa da
-1
opçãols
, pois é automático quandols
está gravando em um pipe. (A menos que você tenha umls
alias para sempre usar o modo de coluna. Já vi isso antes, mas não com muita frequência.)Um
lc
alias é bastante útil em geral, e para esta pergunta, se você olhar para o caso "conte o diretório atual",ls|lc
é o mais sucinto possível.fonte
Até agora, a Aaron é a única abordagem mais sucinta que a sua. Uma versão mais correta da sua abordagem pode parecer com:
Que lista recursivamente todos os arquivos - e não os diretórios - um por linha, incluindo arquivos .dot sob o diretório atual, usando shell globs conforme necessário para substituir caracteres não imprimíveis. O grep filtra todas as listagens de diretório pai ou .. ou * / ou linhas em branco - portanto, deve haver apenas uma linha por arquivo - cuja contagem total o grep retorna para você. Se você deseja incluir diretórios filhos, faça:
Remova os
-R
dois casos, se você não deseja resultados recursivos.fonte
find
. Se você deseja apenas uma contagem, isso deve funcionar:find -mindepth 1 -maxdepth 1 -printf '\n'|wc -l
(remova os controles de profundidade para obter resultados recursivos).find . \! -name . -prune | wc -l
- o que ainda não funciona, é claro.printf
instrução imprime uma string constante (uma nova linha) que não inclui o nome do arquivo, portanto os resultados são independentes de qualquer nome de arquivo estranho. Esse truque não pode ser feito com umfind
que não suportaprintf
, é claro.find .//. \!. -name . -prune | grep -c '^\.//\.'
/
sendo o único outro caractere que não pode aparecer nos nomes dos arquivos, a.//.
sequência é garantida para aparecer exatamente uma vez para cada arquivo, certo? algumas perguntas: por que.//.
e por quê-prune
? quando isso seria diferentefind . \! -name . | grep -c '^\.'
? (i assumir a.
sua\!.
é um erro de digitação.)