Rekursives Finden der größten Datei

41

Ich versuche, die größte Datei in einem Verzeichnis rekursiv zu finden. Befindet sich in diesem Verzeichnis ein Unterverzeichnis, muss die Funktion in dieses Verzeichnis wechseln und prüfen, ob die größte Datei vorhanden ist. Sobald die größte Datei gefunden wurde, wird die Ausgabe mit dem relativen Pfadnamen sowie dem Namen und der Größe der größten Datei angezeigt.

EX:

dude@shell2 (~...assignment/solutions) % bash maxfile.sh ~/test
class/asn
dude.h.gch: 9481628

Das habe ich:

#!/bin/sh
clear

recursiveS() {
    for d in *; do
        if [ -d $d ]; then
            (cd $d; echo $(pwd)/$line; du -a; recursiveS;)
        fi
    done
}
recursiveS

Ich stecke jetzt schon eine Weile fest. Ich kann dies nicht implementieren, indem ich eine Reihe vorhandener Unix-Tools in die Pipeline schreibe. Irgendwelche Ideen wären nett!

user2419571
quelle
in nur subdirs gehen: for d in */ .[^.]*/; do ... `
Olivier Dulac

Antworten:

54

Verwenden Sie find(hier unter der Annahme von GNU find), um Dateinamen mit der Dateigröße auszugeben. Sortieren. drucke den größten aus.

find . -type f -printf "%s\t%p\n" | sort -n | tail -1

Dies setzt voraus, dass die Dateipfade keine Zeilenumbrüche enthalten.


Verwenden einer Schleife in bashder GNU-Implementierung von stat:

shopt -s globstar
max_s=0
for f in **; do
  if [[ -f "$f" && ! -L "$f" ]]; then
    size=$( stat -c %s -- "$f" )
    if (( size > max_s )); then
      max_s=$size
      max_f=$f
    fi
  fi
done
echo "$max_s $max_f"

Dies ist erheblich langsamer als die Find-Lösung. Das setzt auch voraus, dass Dateinamen nicht mit Zeilenumbrüchen enden und versteckte Dateien überspringen und nicht in versteckte Verzeichnisse absteigen.

Wenn sich -im aktuellen Verzeichnis eine Datei mit dem Namen befindet , wird die Größe der in stdin geöffneten Datei berücksichtigt.

Beachten Sie, dass Versionen bashvor 4.3 beim Abstieg in den Verzeichnisbaum symbolischen Links gefolgt sind.

Glenn Jackman
quelle
Danke, es funktioniert! Ich schätze die Hilfe. Ich versuche mich an das Programmieren in der Shell zu gewöhnen. Ich weiß im Moment nicht viel, deshalb weiß ich es zu schätzen, dass Sie mir sagen, was mit dieser Codezeile passiert.
user2419571
Schnelle Frage: Aus Neugier gibt es eine Möglichkeit, dies ohne Piping-Befehle zu tun? Ich bin neugierig, weil bei jedem Beispiel, das ich gesehen habe, Rohrleitungen verwendet wurden.
user2419571
2
Ich bin mir sicher, dass es auch andere Möglichkeiten gibt. Die UNIX-Philosophie besagt, dass Tools nur einen Zweck erfüllen und miteinander verkettet werden müssen, damit die Ausgabe eines Befehls in die Eingabe des nächsten Befehls eingespeist wird.
Glenn Jackman
Das macht Sinn. Nochmals vielen Dank für Ihre Hilfe.
user2419571
2
@ user2419571:; tail -n 1 <(sort -n <(find . -type f -printf "%s\t%p\n")))
Cyrus
9

Mit diesem Befehl können Sie auch die definierte Größe auflisten.

find . -type f -size +100M -exec ls -lh {} \;
senthil sivasamy
quelle
5

Dies funktioniert unter BSD / macOS:

find . -type f -ls | sort -k7 -r

Sie können auch | head -n 3an die Anzahl der interessanten Einträge anhängen (in diesem Fall 3).

CeDeROM
quelle
1
Diese Antwort könnte verbessert werden, indem erklärt wird, wie es funktioniert. Außerdem sieht es der akzeptierten Antwort sehr ähnlich (was auch nicht vollständig erklärt, wie es funktioniert).
Dhag
man findund man sort, benutze brainz :-)
CeDeROM
Funktioniert unter MacOS nicht wirklich, da die Größe nicht korrekt zurückgegeben wird und eine große Anzahl von Spalten zurückgegeben wird.
Sorin
3

Mit zsh, für die größte reguläre Datei:

ls -ld -- **/*(.DOL[1])

(Natürlich können Sie sie durch einen ls -ld --beliebigen Befehl ersetzen . Wenn Sie GNU lsoder ein kompatibles Gerät verwenden, lesen Sie auch die -hOption für vom Menschen lesbare Größen. )

  • .: nur normale Dateien (keine Verzeichnisse, Symlinks, Geräte, Fifos ...)
  • D: schließen Sie versteckte ein und steigen Sie in versteckte dirs ab
  • OL: In umgekehrter Reihenfolge nach Größe ( LLänge).
  • [1]: nur das erste Spiel.

Wenn es Unentschieden gibt, bekommst du eines nach dem Zufallsprinzip. Wenn Sie die erste alphabetisch sortieren möchten, fügen Sie eine weitere hinzu on( order by name), um die Verbindungen alphabetisch zu sortieren.

Beachten Sie, dass die Dateigröße und nicht die Festplattennutzung berücksichtigt wird.

Stéphane Chazelas
quelle
... Ich fange an zu glauben, dass Sie auf der Gehaltsliste von zsh stehen;) (was könnte das wohl sein?). zsh ist leider nicht auf allen Systemen verfügbar ...
Olivier Dulac
Möglich, die ersten zehn Dateien zu bekommen? (Ohne etwas Dummes wie eine Schleife zu tun)
Wowfunhappy
1
@Wowfunhappy ersetzen [1]durch[1,10]
Stéphane Chazelas