Mesurer l'espace disque de certains types de fichiers dans leur ensemble
Question
J'ai quelques fichiers sur plusieurs dossiers:
/home/d/folder1/a.txt
/home/d/folder1/b.txt
/home/d/folder1/c.mov
/home/d/folder2/a.txt
/home/d/folder2/d.mov
/home/d/folder2/folder3/f.txt
Comment puis-je mesurer la grande quantité totale d'espace disque occupé par tous les fichiers txt dans / home / d /?
Je sais que du me donner l'espace total d'un dossier donné et ls -l me donnera l'espace total de fichiers individuels , mais si je veux d'additionner tous les fichiers txt et il suffit de regarder à la espace occupé par tous les fichiers txt dans un total de géant pour tous txt dans / home / d / y compris les folder1 et dossier2 et leurs sous-dossiers comme folder3 ?
La solution
fera:
total=0
for file in *.txt
do
space=$(ls -l "$file" | awk '{print $5}')
let total+=space
done
echo $total
Autres conseils
find folder1 folder2 -iname '*.txt' -print0 | du --files0-from - -c -s | tail -1
rapportera l'utilisation de l'espace disque en octets par extension:
find . -type f -printf "%f %s\n" |
awk '{
PARTSCOUNT=split( $1, FILEPARTS, "." );
EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT];
FILETYPE_MAP[EXTENSION]+=$2
}
END {
for( FILETYPE in FILETYPE_MAP ) {
print FILETYPE_MAP[FILETYPE], FILETYPE;
}
}' | sort -n
Sortie:
3250 png
30334451 mov
57725092729 m4a
69460813270 3gp
79456825676 mp3
131208301755 mp4
simple:
du -ch *.txt
Si vous voulez juste l'espace total prises pour se présenter, puis:
du -ch *.txt | tail -1
Voici une façon de le faire (sous Linux, en utilisant GNU coreutils du
et la syntaxe Bash), évitant mauvaise pratique :
total=0
while read -r line
do
size=($line)
(( total+=size ))
done < <( find . -iname "*.txt" -exec du -b {} + )
echo "$total"
Si vous voulez exclure le répertoire courant, utilisez -mindepth 2
avec find
.
Une autre version qui ne nécessite pas la syntaxe de Bash:
find . -iname "*.txt" -exec du -b {} + | awk '{total += $1} END {print total}'
Notez que ceux-ci ne fonctionnent pas correctement avec les noms de fichiers qui comprennent des sauts de ligne (mais ceux qui ont des espaces Travaillera).
macOS
- utilisez l'outil
du
et le paramètre-I
pour exclure tous les autres fichiers
Linux
-X, --exclude-from=FILE
exclude files that match any pattern in FILE
--exclude=PATTERN
exclude files that match PATTERN
trouver GNU,
find /home/d -type f -name "*.txt" -printf "%s\n" | awk '{s+=$0}END{print "total: "s" bytes"}'
Miser sur ce ennuikiller, cela gérer les espaces dans les noms. Je devais faire cela et un petit rapport:
trouver -type f -name "* .wav" | grep export | ./calc_space
#!/bin/bash
# calc_space
echo SPACE USED IN MEGABYTES
echo
total=0
while read FILE
do
du -m "$FILE"
space=$(du -m "$FILE"| awk '{print $1}')
let total+=space
done
echo $total
A une doublure pour ceux avec des outils GNU sur bash:
for i in $(find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u); do echo "$i"": ""$(du -hac **/*."$i" | tail -n1 | awk '{print $1;}')"; done | sort -h -k 2 -r
Vous devez avoir activé extglob:
shopt -s extglob
Si vous voulez que les fichiers point à travailler, vous devez exécuter
shopt -s dotglob
Exemple de sortie:
d: 3.0G
swp: 1.3G
mp4: 626M
txt: 263M
pdf: 238M
ogv: 115M
i: 76M
pkl: 65M
pptx: 56M
mat: 50M
png: 29M
eps: 25M
etc
J'aime utiliser trouver en combinaison avec xargs:
find . -name "*.txt" -print0 |xargs -0 du -ch
Ajoutez la queue si vous voulez voir le grand total
find . -name "*.txt" -print0 |xargs -0 du -ch | tail -n1
ma solution pour obtenir une taille totale de tous les fichiers texte dans un chemin donné et sous-répertoires (en Perl oneliner)
find /path -iname '*.txt' | perl -lane '$sum += -s $_; END {print $sum}'
Pour tous ceux qui veulent le faire avec macOS à la ligne de commande, vous avez besoin d'une variation en fonction de l'argument -print0 au lieu de printf. Certaines des réponses ci-dessus adresse qui mais cela faire globalement par extension:
find . -type f -print0 | xargs -0 stat -f "%N %i" |
awk '{
PARTSCOUNT=split( $1, FILEPARTS, "." );
EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT];
FILETYPE_MAP[EXTENSION]+=$2
}
END {
for( FILETYPE in FILETYPE_MAP ) {
print FILETYPE_MAP[FILETYPE], FILETYPE;
}
}' | sort -n
Il y a plusieurs problèmes potentiels avec la réponse acceptée:
- il ne descend pas dans les sous-répertoires (sans compter sur les fonctions du shell non standard comme
globstar
) - en général, comme l'a souligné Dennis Williamson ci-dessous, vous devriez éviter analysant la sortie de
ls
- à savoir si l'utilisateur ou le groupe (colonnes 3 et 4) ont des espaces en eux, la colonne 5 ne sera pas la taille du fichier
- si vous avez un million de ces fichiers, ce pondra deux millions de sous-couches, et ce sera sloooow
proposé par ghostdog74 , vous pouvez utiliser l'option -printf
GNU spécifique à find
pour parvenir à une solution plus robuste, en évitant tous les tuyaux excessifs, sous-couches, Perl et étranges options du
:
# the '%s' format string means "the file's size"
find . -name "*.txt" -printf "%s\n" \
| awk '{sum += $1} END{print sum " bytes"}'
Oui, oui, des solutions utilisant paste
ou bc
sont également possibles, mais pas plus simple.
Sur Mac OS, vous devez utiliser Homebrew ou MacPorts installer findutils
et appeler gfind
à la place. (I voir le tag "linux" sur cette question, mais il est aussi tagged "unix".)
Sans GNU find
, vous pouvez toujours revenir à l'aide du
:
find . -name "*.txt" -exec du -k + \
| awk '{kbytes+=$1} END{print kbytes " Kbytes"}'
... mais vous devez être conscient du fait que la sortie par défaut de du
est blocs de 512 octets pour des raisons historiques (voir la section « LOGIQUE » ) et certaines versions de du
(notamment, macOS de) ne sera même pas Vous une option pour imprimer la taille en octets.
Beaucoup d'autres solutions bien ici (voir de href="https://stackoverflow.com/a/14771141/785213"> Grange en particulier), mais la plupart souffrent l'inconvénient d'être inutilement complexes ou en fonction trop sur GNU ne dispose et peut-être dans votre environnement, c'est OK!