Domanda

Ho alcuni file tra diverse cartelle:

/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

Come posso misurare la quantità totale complessivo di spazio su disco occupato da tutti i file .txt in / home / d /?

So du mi darà lo spazio totale di una data cartella e ls -l mi darà lo spazio totale di singoli file , ma cosa succede se voglio per aggiungere tutti i file txt e basta guardare la spazio occupato da tutti i file .txt in un totale gigante per tutti .txt in / home / d / compreso sia cartella1 e cartella2 e relative sottocartelle come Folder3 ?

È stato utile?

Soluzione

Questo lo farà:

total=0
for file in *.txt
do
    space=$(ls -l "$file" | awk '{print $5}')
    let total+=space
done
echo $total

Altri suggerimenti

find folder1 folder2 -iname '*.txt' -print0 | du --files0-from - -c -s | tail -1

Questo riporterà l'utilizzo dello spazio su disco in byte per estensione:

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

Output:

3250 png
30334451 mov
57725092729 m4a
69460813270 3gp
79456825676 mp3
131208301755 mp4

Semplice:

du -ch *.txt

Se si vuole solo lo spazio totale preso a presentarsi, allora:

du -ch *.txt | tail -1

Ecco un modo per farlo (in Linux, utilizzando coreutils GNU du e la sintassi Bash), evitando cattiva pratica :

total=0
while read -r line
do
    size=($line)
    (( total+=size ))
done < <( find . -iname "*.txt" -exec du -b {} + )
echo "$total"

Se si vuole escludere la directory corrente, utilizzare -mindepth 2 con find.

Un'altra versione che non richiede la sintassi Bash:

find . -iname "*.txt" -exec du -b {} + | awk '{total += $1} END {print total}'

Si noti che questi non funzionano correttamente con i nomi di file che includono nuove righe (ma quelli con spazi funzionerà).

MacOS

  • utilizzare lo strumento du e il parametro -I per escludere tutti gli altri file

Linux

-X, --exclude-from=FILE
              exclude files that match any pattern in FILE

--exclude=PATTERN
              exclude files that match PATTERN

GNU trovare,

find /home/d -type f -name "*.txt" -printf "%s\n" | awk '{s+=$0}END{print "total: "s" bytes"}'

Sulla base di ennuikiller, questo sarà gestire gli spazi nei nomi. Avevo bisogno di fare questo e ottenere un po 'di report:

find -type f -name "* .wav" | grep esportazione | ./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 uno di linea per le persone con strumenti GNU su 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

È necessario disporre di extglob abilitato:

shopt -s extglob

Se si desidera che i file di punti a lavorare, è necessario eseguire

shopt -s dotglob

Esempio di output:

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

Mi piace usare trovare in combinazione con xargs:

find . -name "*.txt" -print0 |xargs -0 du -ch

Aggiungi coda se si desidera visualizzare solo il totale

find . -name "*.txt" -print0 |xargs -0 du -ch | tail -n1

la mia soluzione per ottenere una dimensione totale di tutti i file di testo in un determinato percorso e le sottodirectory (usando oneliner perl)

find /path -iname '*.txt' | perl -lane '$sum += -s $_; END {print $sum}'

Per tutti coloro che vogliono fare questo con MacOS dalla riga di comando, è necessario una variazione in base all'argomento -print0 invece di printf. Alcune delle risposte di cui sopra affrontare che, ma questo lo farà completo per estensione:

    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

Ci sono diversi problemi potenziali con la risposta accettata:

  1. non scende in sottodirectory (senza fare affidamento su caratteristiche shell non standard come globstar )
  2. in generale, come sottolineato da Dennis Williamson di seguito, si dovrebbe evitare di verificando l'output del ls
    • cioè, se l'utente o gruppo (colonne 3 e 4) hanno spazi tra loro, colonna 5 non sarà la dimensione del file
  3. se si dispone di un milione di questi file, questo deporrà le uova due milione sottoshell, e sarà sloooow

proposto da ghostdog74 , è possibile utilizzare l'opzione -printf GNU-specifico per find per ottenere una soluzione più robusta, evitando tutte le eccessive tubi, sottoshell, Perl, e opzioni du strani:

# the '%s' format string means "the file's size"
find . -name "*.txt" -printf "%s\n" \
  | awk '{sum += $1} END{print sum " bytes"}'

Sì, sì, le soluzioni che utilizzano paste o bc sono possibili, ma non più semplice.

su MacOS, si avrebbe bisogno di utilizzare Homebrew o MacPorts installare findutils, e chiamare gfind invece. (I il tag vedere "Linux" a questa domanda, ma è anche taggati "unix".)

Senza GNU find, è ancora possibile ripiegare ad usare du:

find . -name "*.txt" -exec du -k + \
  | awk '{kbytes+=$1} END{print kbytes " Kbytes"}'

... ma devi essere consapevole del fatto che la produzione di default di du è in blocchi di 512 byte per ragioni storiche (si veda la sezione "Motivazione" qui ), e alcune versioni di du (in particolare, di MacOS) non sarà nemmeno sono la possibilità di stampare i formati in byte.

Molte altre soluzioni bene qui (vedi Barn risposta in particolare), ma la maggior parte l'inconveniente di essere inutilmente complesse o a seconda troppo pesantemente su GNU-solo le caratteristiche, e forse nel proprio ambiente, che è OK!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top