du zählt die Anzahl der Dateien / Verzeichnisse und nicht die Größe

13

Ich versuche, eine Festplatte zu bereinigen, auf der sich im Laufe der Jahre alle Arten von Mist angesammelt haben. duhat dazu beigetragen, die Festplattennutzung zu reduzieren, aber das Ganze ist immer noch unhandlich, nicht aufgrund der Gesamtgröße, sondern aufgrund der bloßen Anzahl von Dateien und Verzeichnissen insgesamt.

Gibt es eine Möglichkeit, etwas zu tun du, ohne die Dateigröße zu zählen, sondern die Anzahl der Dateien und Verzeichnisse? Beispiel: Eine Datei ist 1, und ein Verzeichnis ist die rekursive Anzahl der darin enthaltenen Dateien / Verzeichnisse + 1.

Edit: Ich hätte klarer sein sollen. Ich möchte nicht nur auf die Gesamtzahl der Dateien / Verzeichnisse kennen /, sondern auch in /home, /usretc, und in Unterverzeichnisse rekursiv, wie dutut für Größe.

Jesse
quelle
2
Denken Sie, Sie suchen vielleicht nach einer leicht modifizierten Version der Antworten hier superuser.com/questions/198817/…
James

Antworten:

11

Ich habe es du --inodesnützlich gefunden , bin mir aber nicht sicher, welche Version dudavon erforderlich ist. Unter Ubuntu 17.10 funktioniert Folgendes:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

Kombinieren Sie mit | sort -nr, um absteigend nach der Anzahl der enthaltenen Inodes zu sortieren.

krlmlr
quelle
1
Das sieht viel mehr nach dem aus, was ich will, als nach der akzeptierten Antwort.
Sridhar Sarnobat
8

Der einfachste Weg scheint zu sein find /path/to/search -ls | wc -l

Suchen wird verwendet, um alle Dateien und Ordner zu durchsuchen.
-lsalle Namen auflisten (drucken). Dies ist eine Standardeinstellung, und wenn Sie sie weglassen, funktioniert sie fast auf allen Systemen gleich. (Fast, da einige unterschiedliche Standardeinstellungen haben könnten). Es ist jedoch eine gute Angewohnheit, dies explizit zu verwenden.

Wenn Sie nur das find /path/to/search -lsTeil verwenden, werden alle Dateien und Verzeichnisse auf Ihrem Bildschirm gedruckt.


wcist die Wortzahl. Die -lOption weist es an, die Anzahl der Zeilen zu zählen.

Sie können es auf verschiedene Arten verwenden, z

  • wc Testdatei
  • Katzentestdatei | Toilette

Mit der ersten Option können wir eine Datei öffnen und die Anzahl der Zeilen, Wörter und Zeichen in dieser Datei zählen. Die zweite Option macht dasselbe, liest aber ohne Dateinamen von stdin.


Sie können Befehle mit einer Pipe kombinieren |. Die Ausgabe des ersten Befehls wird an die Eingabe des zweiten Befehls weitergeleitet. So find /path/to/search -ls | wc -lfinden Anwendungen alle Dateien und Verzeichnisse aufzulisten und speist die Ausgabe WC. Wc zählt dann die Anzahl der Zeilen.

(Eine andere Alternative wäre "ls | wc" gewesen, aber find ist viel flexibler und ein gutes Werkzeug zum Lernen.)


[Nach Kommentar bearbeiten]

Es kann nützlich sein, find und exec zu kombinieren.

ZB find / -type d ! \( -path proc -o -path dev -o -path .snap \) -maxdepth 1 -exec echo starting a find to count to files in in {} \;werden alle Verzeichnisse in / aufgelistet, einige, die Sie nicht durchsuchen möchten. Wir können den vorherigen Befehl für jeden von ihnen auslösen und eine Summe von Dateien pro Ordner in / ergeben.

Jedoch:

  1. Dies verwendet die GNU-spezifische Erweiterung -maxdepth.
    Es funktioniert unter Linux, aber nicht unter Unix-a-Alike.
  2. Ich vermute, Sie möchten tatsächlich eine Anzahl von Dateien für jedes Unterverzeichnis.
Hennes
quelle
Tut mir leid, aber nicht nur eine Ebene tief, sondern für alle Ebenen (das habe ich in meiner Bearbeitung mit "rekursiv" gemeint).
Jesse
Anstelle des Exec-Echos lösen Sie einen Find | aus wc für jedes dir. Ich weiß, dass es möglich ist, aber ich kann nicht herausfinden, wie es heute ist. Ich denke, ich mache immer wieder den gleichen Fehler. * Geht Kaffee kochen *.
Hennes
4

Das folgende PHP-Skript macht den Trick.

#!/usr/bin/php
<?php 

function do_scan($dir, $dev) {
  $total = 1;

  if (\filetype($dir) === 'dir' && \lstat($dir)['dev'] == $dev) {
    foreach (\scandir($dir) as $file) {
      if ($file !== '.' && $file !== '..') {
        $total += do_scan($dir . \DIRECTORY_SEPARATOR . $file, $dev);
      }
    }

    print "$total\t$dir\n";
  }

  return $total;
};

foreach (\array_slice($argv, 1) as $arg) {
  do_scan($arg, \lstat($arg)['dev']);
}

Legen Sie das in eine Datei (sagen wir " treesize") chmod +xund führen Sie es mit aus ./treesize . | sort -rn | less.

Jesse
quelle
Warum ist das die akzeptierte Antwort?! Sie gehen davon aus, dass sich PHP auf dem Computer befindet, was nicht immer der Fall ist. Das Skript ist nicht dokumentiert und spezifisch. Es ist zwar in Ordnung, Ihre eigene Frage zu SE zu beantworten, diese Antwort liefert jedoch nicht einmal eine Antwort auf Ihre eigene Frage . oder Sie haben die Frage, die Sie sich gestellt haben, als das Problem auftrat, nicht gestellt ... Leider kann ich sie nicht ablehnen, ich habe nur wenige Punkte ... trotzdem schlechte Antwort!
user1810087
Ich kann das Skript in keiner Sprache schreiben, ohne davon auszugehen, dass ein Interpreter für diese Sprache installiert ist. Das Skript druckt die Gesamtzahl der Dateien und Verzeichnisse unter jedem Verzeichnis rekursiv. Also eine du, die einfach zählt, anstatt die Größe zu summieren, genau das hat die ursprüngliche Frage gestellt.
Jesse
2

ncdu ist großartig dafür!

Auf der Manpage können Sie auch die Anzahl pro Verzeichnis und die Reihenfolge nach Anzahl anzeigen:

[...]
KEYS
       C   Order by number of items (press again for descending order)
[...]
       c   Toggle display of child item counts.

Zum Beispiel:

ncdu Ausgabe

jobevers
quelle
1

Nutzen Sie die Tatsache, dass Verzeichnisse und Dateien durch getrennt sind /. Dieses Skript erfüllt zwar Ihre Kriterien, dient jedoch als Inspiration für eine vollständige Lösung. Sie sollten auch erwägen, Ihre Dateien mit find zu indizieren.

geee: /R/tb/tmp
$ find  2>/dev/null | awk -F/ -f filez  | sort -n
files:  57
3       imagemagick
7       portage
10      colemak-1.0
25      minpro.com
42      monolith
80      QuadTree
117     themh
139     skyrim.stings
185     security-howto
292     ~t
329     skyrim
545     HISTORY
705     minpro.com-original
1499    transmission-2.77
23539   ugent-settings

>

$ cat filez
{
a[$2]++;     # $1= folder,  $2 = everything inside folder.
}

END {
        for (i in a) {
                if (a[i]==1) {files++;}
                else { printf "%d\t%s\n", a[i], i; }
        }
        print "files:\t" files
}

>

 $ time locate /  | awk -F/ -f /R/tb/tmp/filez  | sort -n
 files:  13
 2
 2       .fluxbox
 10      M
 11      BIN
 120     bin
 216     sbin
 234     boot
 374     R
 854     dev
 1351    lib
 2018    etc
 9274    media
 30321   opt
 56516   home
 93625   var
 222821  usr
 351367  mnt
 time: Real 0m17.4s  User 0m4.1s  System 0m3.1s
Ярослав Рахматуллин
quelle
2
Warum habe ich .fluxbox in /? : D
Ярослав Рахматуллин
1

Hier ist eine Lösung, die Bash verwendet, inspiriert von einem Beitrag von Unix & Linux .

find . -type d | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Wenn es einige Ordner gibt, deren Details Sie nicht sehen möchten .git, können Sie sie von der Liste mit ausschließen grep.

find . -type d |grep -v "./.git/.*" | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Don Kirkby
quelle