J'apprends le script bash et j'ai écrit un script pour compter les fichiers et répertoires dans le répertoire fourni en argument. Je le fais fonctionner d'une manière qui me semble étrange et je me demande s'il existe une façon plus simple de le faire.
J'ai commenté le code qui fonctionnera, mais je l'ai laissé à titre de comparaison. J'essaie de faire fonctionner la boucle for
-, au lieu d'utiliser des instructions if
à l'intérieur pour détecter si un élément à l'emplacement donné est un fichier ou un répertoire.
Edit: Je viens de découvrir que le code commenté compte également tous les fichiers et répertoires dans les sous-répertoires de l'emplacement donné! Existe-t-il un moyen d'empêcher cela et de simplement compter les fichiers et répertoires de l'emplacement donné?
#!/bin/bash
LOCATION=$1
FILECOUNT=0
DIRCOUNT=0
if [ "$#" -lt "1" ]
then
echo "Usage: ./test2.sh <directory>"
exit 0
fi
#DIRS=$(find $LOCATION -type d)
#FILES=$(find $LOCATION -type f)
#for d in $DIRS
#do
# DIRCOUNT=$[$DIRCOUNT+1]
#done
#for f in $FILES
#do
# FILECOUNT=$[$FILECOUNT+1]
#done
for item in $LOCATION
do
if [ -f "$item" ]
then
FILECOUNT=$[$FILECOUNT+1]
Elif [ -d "$item" ]
then
DIRCOUNT=$[$DIRCOUNT+1]
fi
done
echo "File count: " $FILECOUNT
echo "Directory count: " $DIRCOUNT
Pour une raison quelconque, la sortie de la boucle for
-, peu importe où je pointe l'emplacement, renvoie toujours:
File count: 0 , Directory count: 1
Vous n'êtes pas en train d'itérer sur la liste des fichiers dans le répertoire donné; ajouter /*
après $LOCATION
. Votre script devrait ressembler à:
...
for item in $LOCATION/*
do
...
Comme l'a souligné Dogbane, il suffit d'ajouter /*
ne comptera que les fichiers qui ne commencent pas par .
; pour ce faire, vous devez procéder comme suit:
...
for item in $LOCATION/* $LOCATION/.*
do
...
Utilisez find
comme indiqué ci-dessous. Cette solution comptera correctement les noms de fichiers avec des espaces, des nouvelles lignes et des fichiers dot.
FILECOUNT="$(find . -type f -maxdepth 1 -printf x | wc -c)"
DIRCOUNT="$(find . -type d -maxdepth 1 -printf x | wc -c)"
Notez que DIRCOUNT
inclut le répertoire courant (.
). Si vous ne le souhaitez pas, soustrayez 1.
((DIRCOUNT--)) # to exclude the current directory
Pour simplement résoudre le problème, vous pouvez utiliser:
FILECOUNT=$(find $LOCATION -type f | wc -l)
DIRCOUNT=$(find $LOCATION -type d | wc -l)
find
recherchera tous les fichiers (-type f
) ou répertoires (-type d
) récursivement sous $LOCATION
; wc -l
Comptera le nombre de lignes écrites sur stdout dans chaque cas.
Cependant, si vous voulez apprendre, le script bash peut être un meilleur moyen. Certains commentaires:
$LOCATION
Uniquement (pas de manière récursive sous leurs sous-répertoires, etc.), vous pouvez utiliser for item in $LOCATION/*
, Où *
S'étendra à la liste des fichiers/répertoires dans le répertoire $LOCATION
. Le *
Manquant est la raison pour laquelle votre script d'origine renvoie 0/1 (car le répertoire $LOCATION
Lui-même est le seul élément compté).$LOCATION
Est en fait un répertoire avec [ -d $LOCATION ]
.$(( ... ))
, par exemple FILECOUNT=$(( FILECOUNT + 1 ))
.find
avec une boucle.Exemple:
find $LOCATION | while read item; do
# use $item here...
done
... am wondering if there is a simpler way of doing it.
Si tu le dis ;)
Vous pouvez également réduire votre script à
find /path/to/directory | wc -l
Pour le répertoire actuel, faites:
find . | wc -l
Utilisation
find $LOCATION -maxdepth 1 -type f | wc -l
Pour le nombre de fichiers, et
find $LOCATION -maxdepth 1 -type d | wc -l
Pour compter les répertoires