Contando arquivos na pasta sem wc

3

Por que os seguintes scripts fornecem uma contagem de 0 em vez de fornecer a contagem de arquivos presentes no diretório?

#!/bin/bash
cd /root/Jamshed/script
count=0
ls -lrt > all_files
cat all_files | while read dir
do  
    count=$(($count + 1))
done
echo $count;
    
por Jamshed Ansari user3000272 16.02.2014 / 09:43

5 respostas

6

Ele está dando o count como zero porque você está incrementando count dentro de um subshell. Como tal, as alterações feitas para a variável são perdidas .

Em vez disso, diga:

while read -r dir
do  
    count=$(($count + 1))
done < all_files

para alcançar o resultado desejado.

Dito isto, parsing ls nunca é recomendado.

    
por 16.02.2014 / 09:53
3

Você pode usar uma matriz para armazenar os nomes dos arquivos e examinar o tamanho da matriz:

files=( /root/Jamshed/script/* )
echo "${#files[@]}"

Se você quiser todos os arquivos recursivamente:

shopt -s globstar nullglob
files=( /root/Jamshed/script/** )
echo "${#files[@]}"
    
por 16.02.2014 / 12:39
1

Você pode fazer isso sem analisar ls output ou usando wc da seguinte forma:

cd /root/Jamshed/script
count=0
shopt -s nullglob
for file in * .*[!.]*;do
    count=$(($count+1))
done
echo $count

Explicação

O padrão de glob * corresponderá a todos os nomes de arquivos e diretórios que não iniciam com . e o padrão de glob .*[!.]* corresponderá a todos os nomes de arquivos e diretórios cujo nome comece com . e contenha pelo menos um caractere não . (para evitar a contagem dos diretórios especiais . e .. ).

    
por 16.02.2014 / 11:47
0

Seu script funciona bem em ksh, você também pode alterar a primeira linha (no Linux, o pacote ksh deve ter sido instalado).
#!/bin/ksh ksh doen não usa subshells em um loop.

    
por 18.02.2014 / 10:02
0

Em vez de usar bash substituir o processo , você pode - de bash 4.2 on - usar shopt -s lastpipe para evitar a subshell problema (atribuição de variável no processo filho não é visível no shell pai).

(Ainda outra maneira de evitar o problema de subshell é usar exec e redirecionar stdin de um arquivo ou heredoc).

Se você insistir em usar ls , use ls -1Artb .

# file version
set +f
shopt -s nullglob dotglob
count=0
printf '%s
# file version
set +f
shopt -s nullglob dotglob
count=0
printf '%s%pre%0' * > all_files
while IFS="" read -r -d "" file; do
   test -z "$file" && continue
   count=$(($count + 1))
   #printf '%s\n' "$count: $file"
done < all_files
echo "$count"

# process substitution version
set +f
shopt -s nullglob dotglob
count=0
while IFS="" read -r -d "" file; do
   test -z "$file" && continue
   count=$(($count + 1))
   #printf '%s\n' "$count: $file"
done < <(printf '%s%pre%0' *)
echo "$count"
0' * > all_files while IFS="" read -r -d "" file; do test -z "$file" && continue count=$(($count + 1)) #printf '%s\n' "$count: $file" done < all_files echo "$count" # process substitution version set +f shopt -s nullglob dotglob count=0 while IFS="" read -r -d "" file; do test -z "$file" && continue count=$(($count + 1)) #printf '%s\n' "$count: $file" done < <(printf '%s%pre%0' *) echo "$count"
    
por 18.02.2014 / 15:19

Tags