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.

14voto

Seweryn Niemiec Punkte 1003

Ich verwende das hier (sehr effizient):

function find_last () { find "${1:-.}" -type f -printf '%TY-%Tm-%Td %TH:%TM %P\n' 2>/dev/null | sort | tail -n "${2:-10}"; }

PROS:

  • es werden nur 3 Prozesse gestartet, egal wie viele Dateien gescannt werden
  • funktioniert mit Dateinamen, die Leerzeichen enthalten
  • funktioniert bei einer großen Anzahl von Dateien

ANWENDUNG:

find_last [dir [number]]

wo:

  • dir - ein zu durchsuchendes Verzeichnis [current dir]
  • number - Anzahl der neuesten Dateien, die angezeigt werden sollen [10]

Ausgabe für find_last /etc 4 sieht so aus:

2019-07-09 12:12 cups/printers.conf
2019-07-09 14:20 salt/minion.d/_schedule.conf
2019-07-09 14:31 network/interfaces
2019-07-09 14:41 environment

12voto

Serge Stroobandt Punkte 23731

Versteckte Dateien ignorieren - mit schönem & schnellem Zeitstempel

So können Sie die zuletzt geänderten Dateien in einem Verzeichnis mit Unterverzeichnissen finden und auflisten. Versteckte Dateien werden absichtlich ignoriert. Leerzeichen in Dateinamen werden gut behandelt - nicht, dass Sie diese verwenden sollten! Das Zeitformat kann angepasst werden.

$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10

2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht
2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht
2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht
2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht

Mehr find in Hülle und Fülle finden Sie, wenn Sie dem Link folgen.

12voto

Jim DeLaHunt Punkte 10316

Dieser Befehl funktioniert unter Mac OS X:

find "$1" -type f -print0 | xargs -0 gstat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head

Unter Linux, wie der ursprüngliche Poster fragte, verwenden Sie stat anstelle von gstat .

Diese Antwort lautet natürlich, Benutzer37078 Die hervorragende Lösung, die vom Kommentar zur vollständigen Antwort wurde. Ich habe untergemischt CharlesB die Einsicht, dass die gstat unter Mac OS X. Ich habe coreutils von MacPorts よりも Selbstgebrautes Übrigens.

Und so habe ich das Ganze in einen einfachen Befehl verpackt ~/bin/ls-recent.sh zur Wiederverwendung:

#!/bin/bash
# ls-recent: list files in a directory tree, most recently modified first
#
# Usage: ls-recent path [-10 | more]
#
# Where "path" is a path to target directory, "-10" is any argument to pass
# to "head" to limit the number of entries, and "more" is a special argument
# in place of "-10" which calls the pager "more" instead of "head".
if [ "more" = "$2" ]; then
   H=more; N=''
else
   H=head; N=$2
fi

find "$1" -type f -print0 |xargs -0 gstat --format '%Y :%y %n' \
    |sort -nr |cut -d: -f2- |$H $N

5voto

anubhava Punkte 713155

Hier ist eine Version, die mit Dateinamen arbeitet, die auch Leerzeichen, Zeilenumbrüche und globale Zeichen enthalten können:

find . -type f -printf "%T@ %p\0" | sort -zk1nr
  • find ... -printf gibt die Änderungszeit der Datei aus ( Epochenwert ), gefolgt von einem Leerzeichen und \0 beendete Dateinamen.
  • sort -zk1nr liest Daten mit NUL-Ende und sortiert sie umgekehrt numerisch

Da die Frage mit Linux getaggt ist, gehe ich davon aus GNU Core Utilities sind verfügbar.

Sie können den obigen Text mit einem Rohr verbinden:

xargs -0 printf "%s\n"

um die Änderungszeit und die Dateinamen, sortiert nach der Änderungszeit (die jüngste zuerst) und mit Zeilenumbrüchen abgeschlossen, auszugeben.

5voto

William Niu Punkte 15692

Sowohl die Perl- als auch die Python-Lösung in diesem Beitrag haben mir geholfen, dieses Problem unter Mac OS X zu lösen:

Auflistung von Dateien sortiert nach Änderungsdatum rekursiv (kein stat-Befehl verfügbar!)

Ich zitiere aus dem Beitrag:

Perl:

find . -type f -print |
perl -l -ne '
    $_{$_} = -M;  # store file age (mtime - now)
    END {
        $,="\n";
        print sort {$_{$b} <=> $_{$a}} keys %_;  # print by decreasing age
    }'

Python:

find . -type f -print |
python -c 'import os, sys; times = {}
for f in sys.stdin.readlines(): f = f[0:-1]; times[f] = os.stat(f).st_mtime
for f in sorted(times.iterkeys(), key=lambda f:times[f]): print f'

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