573 Stimmen

Rekursives Auffinden und Auflisten der zuletzt geänderten Dateien in einem Verzeichnis mit Unterverzeichnissen und Zeiten

  • Das Betriebssystem: Linux

  • Dateisystem-Typ: ext3

  • Bevorzugte Lösung: Bash (Skript/Einzeiler), Ruby oder Python

Ich habe mehrere Verzeichnisse mit mehreren Unterverzeichnissen und Dateien darin. Ich muss eine Liste all dieser Verzeichnisse erstellen, die so aufgebaut ist, dass jedes Verzeichnis der ersten Ebene neben dem Datum und der Uhrzeit der zuletzt erstellten/geänderten Datei darin aufgeführt ist.

Zur Verdeutlichung: Wenn ich eine Datei berühre oder ihren Inhalt ein paar Unterverzeichnisebenen tiefer ändere, sollte dieser Zeitstempel neben dem Namen des Verzeichnisses der ersten Ebene angezeigt werden. Angenommen, ich habe ein Verzeichnis, das wie folgt strukturiert ist:

./alfa/beta/gamma/example.txt

und ich ändere den Inhalt der Datei example.txt Ich brauche diese Zeit neben dem Verzeichnis der ersten Ebene angezeigt alfa in menschenlesbarer Form, nicht Epoche. Ich habe einige Dinge mit find ausprobiert, xargs , sort und dergleichen, aber ich komme nicht um das Problem herum, dass sich der Dateisystem-Zeitstempel von "alfa" nicht ändert, wenn ich Dateien ein paar Ebenen tiefer anlege/verändere.

3voto

Sean Punkte 31

Ich zeige dies für die letzte Zugriffszeit, und Sie können dies leicht ändern, um die letzte Änderungszeit zu tun.

Es gibt zwei Möglichkeiten, dies zu tun:


  1. Wenn Sie eine globale Sortierung vermeiden wollen, die bei mehreren Millionen Dateien teuer sein kann, können Sie dies tun (positionieren Sie sich im Stammverzeichnis des Verzeichnisses, in dem die Suche beginnen soll):

     Linux> touch -d @0 /tmp/a;
     Linux> find . -type f -exec tcsh -f -c test `stat --printf="%X" {}` -gt  `stat --printf="%X" /tmp/a`  ; -exec tcsh -f -c touch -a -r {} /tmp/a ; -print

    Die obige Methode gibt Dateinamen mit immer neueren Zugriffszeiten aus, und die letzte Datei, die ausgegeben wird, ist die Datei mit der neuesten Zugriffszeit. Sie können die letzte Zugriffszeit natürlich auch mit "tail -1" ermitteln.

  2. Sie können find rekursiv den Namen und die Zugriffszeit aller Dateien in Ihrem Unterverzeichnis ausgeben lassen und dann nach der Zugriffszeit sortieren und den größten Eintrag anhängen:

     Linux> \find . -type f -exec stat --printf="%X  %n\n" {} \; | \sort -n | tail -1

Und da haben Sie es...

3voto

Tagar Punkte 12059

Ich habe diesen Alias in meinem .profile, den ich recht häufig verwende:

$ alias | grep xlogs
xlogs='sudo find . \( -name "*.log" -o -name "*.trc" \) -mtime -1 | sudo xargs ls -ltr --color | less -R'

Es tut also das, wonach Sie suchen (mit der Ausnahme, dass es nicht mehrere Ebenen von Änderungsdatum/Zeit durchläuft) - es sucht nach den neuesten Dateien (in diesem Fall *.log- und *.trc-Dateien); außerdem findet es nur Dateien, die am letzten Tag geändert wurden, und sortiert dann nach Zeit und leitet die Ausgabe durch weniger :

sudo find . \( -name "*.log" -o -name "*.trc" \) -mtime -1 | sudo xargs ls -ltr --color | less -R

PS: Beachten Sie, dass ich auf einigen Servern keinen Root-Zugang habe, aber immer sudo Sie brauchen diesen Teil also möglicherweise nicht.

2voto

linux.cnf Punkte 323

Die Bash hat eine Einzeiler-Skript-Lösung für die rekursive Suche nach zuletzt geänderten Dateien in mehreren Verzeichnissen. Finden Sie bitte untenstehenden Befehl mit Ihren Zielverzeichnissen.

 ls -ltr $(find /path/dir1 /path/dir2 -type f)

und für today, grep today Datum oder Uhrzeit wie im folgenden Befehl angegeben

 (ls -ltr $(find /path/dir1 /path/dir2 -type f)) |grep -i 'Oct 24'

2voto

dancow Punkte 3008

@anubhava's Antwort ist großartig, aber leider funktioniert es nicht mit BSD-Tools - d.h. es funktioniert nicht mit dem find das standardmäßig auf macOS installiert wird weil BSD find hat nicht die -printf Betreiber.

Hier ist also eine Variante, die mit macOS + BSD funktioniert (getestet auf meinem Catalina Mac), die BSD kombiniert find mit xargs y stat :

$ find . -type f -print0 \
      | xargs -0 -n1 -I{} stat -f '%Fm %N' "{}" \
      | sort -rn 

Wenn ich schon mal hier bin, hier eine BSD-Befehlssequenz, die ich gerne verwende und die den Zeitstempel in ISO-8601-Format

$ find . -type f -print0 \
    | xargs -0 -n1 -I{} \
       stat  -f '%Sm %N' -t '%Y-%m-%d %H:%M:%S' "{}" \
    | sort -rn

(Beachten Sie, dass meine beiden Antworten, anders als die von @anubhava, die Dateinamen von find à xargs als einzelnes Argument und nicht als \0 beendete Liste, die das ändert, was ganz am Ende herausgeleitet wird)

Und hier ist die GNU-Version (d.h. die Antwort von @anubhava, aber im iso-8601-Format):

$ gfind . -type f -printf "%T+ %p\0" | sort -zk1nr

Verwandte q: find fehlt die Option -printf, was nun?

2voto

Ilya Yevlampiev Punkte 3251

Für diejenigen, die mit

stat: unrecognized option: format

bei Ausführung der Zeile aus Heppos Antwort ( find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head )

Bitte versuchen Sie die -c Taste zum Ersetzen --format und schließlich wird der Anruf erfolgen:

find $1 -type f -exec stat -c '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head

Das hat bei mir in einigen Docker-Containern funktioniert, wo stat nicht verwenden konnte --format Option.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X