Donc, dans de nombreuses situations, je voulais un moyen de savoir combien d'espace disque est utilisé par quoi, donc je sais de quoi me débarrasser, convertir dans un autre format, stocker ailleurs (comme des DVD de données), passer à une autre partition, etc. Dans ce cas, je regarde une partition Windows à partir d'un support de démarrage SliTaz Linux .
Dans la plupart des cas, ce que je veux, c'est la taille des fichiers et des dossiers, et pour cela j'utilise NCurses ncd :
Mais dans ce cas, je veux un moyen d'obtenir la taille de tous les fichiers correspondant à une expression régulière. Un exemple d'expression régulière pour les fichiers .bak:
.*\.bak$
Comment puis-je obtenir ces informations, en considérant un Linux standard avec le noyau GNU utilitaires ou BusyBox ?
Edit: La sortie est destinée à être analysée par un script.
Je suggère quelque chose comme: find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1
Quelques notes:
-print0
option pour find
et --files0-from
pour du
sont là pour éviter les problèmes avec les espaces dans les noms de fichiers./dir1/subdir2/file.bak
, pas seulement file.bak
, donc si vous le modifiez, tenez-en compteh
pour que du produise un format "lisible par l'homme" mais si vous voulez analyser la sortie, vous pouvez être mieux avec k
(utilisez toujours des kilo-octets)tail
, vous verrez en outre la taille de fichiers et de répertoires particuliersSidenote: un bel outil graphique pour découvrir qui a mangé votre espace disque est FileLight . Il ne fait pas de regex, mais est très pratique pour trouver de gros répertoires ou des fichiers obstruant votre disque.
du
est ma réponse préférée. Si vous avez une structure de système de fichiers fixe, vous pouvez utiliser:
du -hc *.bak
Si vous devez ajouter des sous-répertoires, ajoutez simplement:
du -hc *.bak **/*.bak **/**/*.bak
etc
Cependant, ce n'est pas une commande très utile, donc en utilisant votre recherche:
TOTAL=0;for I in $(find . -name \*.bak); do TOTAL=$((TOTAL+$(du $I | awk '{print $1}'))); done; echo $TOTAL
Cela fera écho à la taille totale en octets de tous les fichiers que vous trouvez.
J'espère que cela pourra aider.
Les solutions précédentes ne fonctionnaient pas correctement pour moi (j'ai eu des problèmes de tuyauterie du
) mais les suivantes ont très bien fonctionné:
find path/to/directory -iregex ".*\.bak$" -exec du -csh '{}' + | tail -1
L'option iregex
est une expression régulière insensible à la casse. Utilisez regex
si vous voulez qu'il soit sensible à la casse.
Si vous n'êtes pas à l'aise avec les expressions régulières, vous pouvez utiliser les drapeaux iname
ou name
(le premier étant insensible à la casse):
find path/to/directory -iname "*.bak" -exec du -csh '{}' + | tail -1
Dans le cas où vous souhaitez la taille de chaque match (plutôt que le total combiné), laissez simplement la commande piped tail:
find path/to/directory -iname "*.bak" -exec du -csh '{}' +
Ces approches évitent le problème de sous-répertoire dans la réponse de @MaddHackers.
J'espère que cela aide les autres dans la même situation (dans mon cas, trouver la taille de toutes les DLL dans une solution .NET).
Exécutez ceci dans un Bourne Shell pour déclarer une fonction qui calcule la somme des tailles de tous les fichiers correspondant à un modèle d'expression régulière dans le répertoire actuel:
sizeofregex() { IFS=$'\n'; for x in $(find . -regex "$1" 2> /dev/null); do du -sk "$x" | cut -f1; done | awk '{s+=$1} END {print s}' | sed 's/^$/0/'; unset IFS; }
(Alternativement, vous pouvez le mettre dans un script.)
tilisation:
cd /where/to/look
sizeofregex 'myregex'
Le résultat sera un nombre (en Kio), y compris 0
(s'il n'y a aucun fichier correspondant à votre expression régulière).
Si vous ne voulez pas qu'il regarde dans d'autres systèmes de fichiers (disons que vous voulez chercher tous les .so
fichiers sous /
, qui est une monture de /dev/sda1
, mais pas sous /home
, qui est une monture de /dev/sdb1
, ajouter un -xdev
paramètre à find
dans la fonction ci-dessus.
Si vous êtes d'accord avec les motifs globaux et que vous êtes uniquement intéressé par le répertoire courant:
stat -c "%s" *.bak | awk '{sum += $1} END {print sum}'
ou
sum=0
while read size; do (( sum += size )); done < <(stat -c "%s" *.bak)
echo $sum
Le %s
la directive stat donne des octets et non des kilo-octets.
Si vous voulez descendre dans des sous-répertoires, avec bash version 4, vous pouvez shopt -s globstar
et utilisez le modèle **/*.bak
La réponse acceptée suggère d'utiliser
find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1
mais cela ne fonctionne pas sur mon système car du
ne connaît pas --files-0-from
option sur mon système. Seul GNU du
connaît cette option, elle ne fait pas partie de la POSIX Standard (donc vous ne la trouverez pas dans FreeBSD ou macOS), ni le trouverez-vous sur systèmes Linux basés sur BusyBox (par exemple la plupart des systèmes Linux embarqués) ou sur tout autre système Linux qui n'utilise pas la version GNU du
.
Ensuite, il y a une réponse suggérant d'utiliser:
find path/to/directory -iregex .*\.bak$ -exec du -csh '{}' + | tail -1
Cette solution fonctionnera tant qu'il n'y aura pas trop de fichiers trouvés, comme +
signifie que find
va essayer d'appeler du
avec autant de hits que possible en un seul appel, cependant, il peut y avoir un nombre maximum d'arguments (N) pris en charge par un système et s'il y en a plus de hits que cette valeur, find
appellera du
plusieurs fois, divisant les hits en groupes inférieurs ou égaux à N éléments chacun et dans ce cas, le résultat sera incorrect et ne montrera que la taille de le dernier du
appel.
Enfin, il existe une réponse en utilisant stat
et awk
, ce qui est une bonne façon de le faire, mais il s'appuie sur Shell globbing d'une manière que seul Bash 4.x ou version ultérieure prend en charge. Il ne fonctionnera pas avec les anciennes versions et s'il fonctionne avec d'autres shells est imprévisible.
Une solution conforme POSIX (fonctionne sur Linux, macOS et toutes les variantes BSD), qui ne souffre d'aucune limitation et qui fonctionnera sûrement avec chaque Shell serait:
find . -regex '.*\.bak' -exec stat -f "%z" {} \; | awk '{s += $1} END {print s}'