So listen Sie Dateien rekursiv nach Änderungsdatum sortiert auf (kein stat-Befehl verfügbar!)

31

Wie kann ich die Liste aller Dateien im aktuellen Verzeichnis zusammen mit ihrem Änderungsdatum abrufen und nach diesem Datum sortieren?

Jetzt weiß ich , wie das zu erreichen , mit find, statund sort, aber aus irgendeinem seltsamen Grunde , die statnicht auf der Box installiert und es ist unwahrscheinlich , dass ich bekommen kann es installiert ist .

Irgendeine andere Option?

PS: gccist auch nicht installiert

Alex
quelle
Können Sie eine kompilierte Binärdatei hochladen und dort ausführen?
imz - Ivan Zakharyaschev
@imz: Ja, das ist ein anderer Weg. Die find -printfAktion scheint jedoch die einfachste zu sein.
Alex

Antworten:

27

Meine kürzeste Methode verwendet zsh:

print -rl -- **/*(.Om)

( DFügen Sie die Glob-Qualifizierer hinzu, wenn Sie auch die versteckten Dateien oder die Dateien in versteckten Verzeichnissen auflisten möchten).

Wenn Sie GNU find haben, lassen Sie es die Datei-Änderungszeiten drucken und danach sortieren. Ich gehe davon aus, dass die Dateinamen keine Zeilenumbrüche enthalten.

find . -type f -printf '%T@ %p\n' | sort -k 1 -n | sed 's/^[^ ]* //'

Wenn Sie Perl haben (auch hier unter der Annahme, dass die Dateinamen keine Zeilenumbrüche enthalten):

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

Wenn Sie Python haben (auch hier unter der Annahme, dass die Dateinamen keine Zeilenumbrüche enthalten):

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'

Wenn Sie über SSH-Zugriff auf diesen Server verfügen, hängen Sie das Verzeichnis über sshfs auf einem besser ausgestatteten Computer an:

mkdir mnt
sshfs server:/path/to/directory mnt
zsh -c 'cd mnt && print -rl **/*(.Om)'
fusermount -u mnt

Mit nur POSIX-Werkzeugen ist es viel komplizierter, da es keine gute Möglichkeit gibt, den Änderungszeitpunkt einer Datei zu ermitteln. Die einzige Standardmethode zum Abrufen der Zeiten einer Datei ist ls, und das Ausgabeformat ist vom Gebietsschema abhängig und schwer zu analysieren.

Wenn Sie in die Dateien schreiben können und sich nur für reguläre Dateien interessieren und es keine neuen Zeilen in den Dateinamen gibt, ist dies ein schrecklicher Fehler: Erstellen Sie feste Links zu allen Dateien in einem einzigen Verzeichnis und sortieren Sie sie nach dem Änderungszeitpunkt.

set -ef                       # disable globbing
IFS='
'                             # split $(foo) only at newlines
set -- $(find . -type f)      # set positional arguments to the file names
mkdir links.tmp
cd links.tmp
i=0 list=
for f; do                     # hard link the files to links.tmp/0, links.tmp/1, …
  ln "../$f" $i
  i=$(($i+1))
done
set +f
for f in $(ls -t [0-9]*); do  # for each file, in reverse mtime order:
  eval 'list="${'$i'}         # prepend the file name to $list
$list"'
done
printf %s "$list"             # print the output
rm -f [0-9]*                  # clean up
cd ..
rmdir links.tmp
Gilles 'SO - hör auf böse zu sein'
quelle
Der einfachste Weg ist wahrscheinlich find . -print | xargs -n99999 -s999999 ls -ltr. Dies hat jedoch das Problem, dass (1) xargsmöglicherweise nicht -mmehr als 512 oder -smehr als 5120 zulässt , und (b) selbst wenn Sie das umgehen können, gibt es immer noch eine vom Kernel festgelegte maximale Größe der kombinierten Argumentliste und -umgebung. Die meisten Ihrer Ideen (außer den Perl- und Python-Ideen) haben das gleiche Problem, weshalb ich ausdrücklich darauf verzichtet habe, lange Befehlszeilen zu erstellen.
Geekosaurier
Insbesondere bekomme zshich im allgemeinen Fall regelmäßig "Argumentliste zu lang" -Fehler mit rekursiven Globs.
Geekosaurier
@geekosaur: Nur der letzte schreckliche Kludge hat ein Problem mit langen Kommandozeilen. In zsh können Sie eine Menge mit eingebauten Funktionen tun ( print -rl **/*die einzige Beschränkung besteht darin, wie viel Speicher Sie haben), und darüber hinaus gibt es noch weitere Funktionen zargs. Ihr Vorschlag von find … | xargs … lswird korrekt sortiert, wenn xargser lsnur einmal aufgerufen wird , und funktioniert nicht, wenn die Dateinamen Sonderzeichen enthalten.
Gilles 'SO - hör auf böse zu sein'
vielen dank für die extrem detaillierte antwort mit vielen möglichkeiten! :)
Alex
Und deshalb liebe ich zsh.
Profpatsch
14

Angenommen, GNU find:

find . -printf '%T@ %c %p\n' | sort -k 1n,1 -k 7 | cut -d' ' -f2-

Wechseln Sie 1n,1zu, 1nr,1wenn Sie möchten, dass die neuesten Dateien zuerst aufgelistet werden.

Wenn Sie GNU nicht haben find, wird es schwieriger, weil lsdas Zeitstempelformat so stark variiert (kürzlich geänderte Dateien haben zum Beispiel einen anderen Zeitstempelstil).

Geekosaurier
quelle
Eigentlich können Sie auch das Datums- und Uhrzeitformat mit ändern ls --time-style="..."- ich bin mir nicht sicher, ob dies Standard oder GNU ls ist, wahrscheinlich GNU.
Asoundmove
Auf jeden Fall GNU.
Geekosaurier
@asoundmove: leider ist die box zu alt (redhat 7.2) und lshat diese option nicht.
Alex
7

Auf einem Mac muss kein -printf-Argument gefunden werden, aber Sie können dies stattdessen tun:

find . -print0 | xargs -0 -n 100 stat -f"%m %Sm %N" | sort -n|awk '{$1="";print}'

killdash9
quelle
0

man kann das probieren (man muss es sich aber selber bauen) https://github.com/shadkam/recentmost

user3392225
quelle
6
Willkommen bei Unix & Linux Stack Exchange! Während dies theoretisch die Frage beantworten mag, wäre es vorzuziehen , die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen.
SLM
0

Versteckte Dateien ignorieren - mit schönem und schnellem Zeitstempel

Behandelt Leerzeichen in Dateinamen gut - nicht, dass Sie diese verwenden sollten!

$ 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

Weitere findInformationen finden Sie unter folgendem Link.

Serge Stroobandt
quelle
0

Apropos Dateien nach Datum zu finden (das funktioniert nicht für das Originalposter, aber ich bin hier gelandet, also dachte ich, andere könnten es auch). In meinem Anwendungsfall möchte ich die Dateien auflisten, um sie vor dem Löschen zu überprüfen.

Mit findutils 4.6.0 mag ich:

find . -type f -mtime +270 -exec ls -laFGht --time-style=iso {} \+

Mit dem obigen Befehl werden Dateien ( -type f) im aktuellen Arbeitsverzeichnis ( .) gefunden, die vor mehr als 270 Tagen geändert wurden ( -mtime +270Außerdem -mtime 0werden die letzten 24 Stunden erstellt und -mtime -5die letzten 5 Tage angezeigt). Es verwendet dann lssie zur Liste nach Datum, neueste zuerst ( -exec ls -laFGht --time-style=iso {} \+)

Hier ist ein Beispiel für die Ausgabe:

-rwxrwx---+ 1 user1 208M 2018-07-16  ./filename.bak*
-rwxrwx---+ 1 user1  702 2018-07-15  ./filename.ldf*
-rwxrwx---+ 1 user1 208M 2018-07-15  ./filename.bak*

Das Tolle daran ist, dass es einfach ist, den findListenteil durch den Befehl delete zu ersetzen, sobald die Liste überprüft wurde :

find . -type f -mtime +270 -delete
Steph
quelle