Minha tarefa era imprimir o número de arquivos no diretório atual sem usar comandos ls
e .wc
Eu digitei as seguintes linhas no script:
#!/bin/bash
find . -maxdepth 1 -type f \( ! -iname ".*" \) > list3
grep .* -c list3 > /dev/tty
A saída é:
..:0
.6.1c.sh.swp:1
list3:22
enquanto, de acordo com meu entendimento, deveria ser apenas:22
Por que isso não funciona?
Responder1
Por que grep
não está funcionando corretamente
Não funciona porque você precisa saber grep
se esse .*
é o padrão real que você está procurando.
grep '.*' -c list3
Se você não usar aspas simples, seu shell se expandirá.*
para os nomes de todos os arquivos em seu diretório. Isso é chamadoExpansão de nome de arquivo. Por exemplo a.txt b.txt
, assim grep
veremos:
grep a.txt b.txt -c list3
Desdeaspas simplesevitar que a expansão aconteça, este é o caminho a seguir aqui.
Onde seu grep
comando está errado:
A propósito, você está indo na direção errada com o padrão aqui. O período.
em uma expressão regular correspondequalquercaractere, e não o ponto literal. Veroman
páginapara mais informações. Portanto, seu regex atualmente diz: "encontre qualquer caractere e depois uma sequência de qualquer caractere". Bastante redundante.
Se você realmente quer combinar:
[ponto] [qualquer outra coisa]
… você precisa escapar do ponto:
\.*
Onde seu find
comando poderia ser melhorado:
Eu não sei o que você quer dizer com se livrar
\( ! -iname ".*" \)
Seu find
comando irá prefixar qualquer arquivo com o ponto do diretório de trabalho atual, portanto você não removerá nada aqui. Você poderia simplesmente ter executado:
find . -maxdepth 1 -type f
Responder2
Para resolver o problema original, contando arquivos sem ls
e wc
:
Sintaxe pura do shell:
files=0
for i in *; do
[ -f "${i}" ] && files=$((files+1))
done
echo ${files}
Para adicionar arquivos ocultos à contagem, basta alterar as configurações de globbing antes do for
loop.
Alternativamente: diversão find
e expansão do shell:
echo $(($(find -maxdepth 1 -type f -printf '+1')))