Es scheint, dass lsdie Dateien bei einem rekursiven Aufruf nicht richtig sortiert werden:
ls -altR . | head -n 3
Wie finde ich die zuletzt geänderte Datei in einem Verzeichnis (einschließlich Unterverzeichnissen)?
Es scheint, dass lsdie Dateien bei einem rekursiven Aufruf nicht richtig sortiert werden:
ls -altR . | head -n 3
Wie finde ich die zuletzt geänderte Datei in einem Verzeichnis (einschließlich Unterverzeichnissen)?
Antworten:
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "
Für einen riesigen Baum könnte es schwierig sein sort, alles im Gedächtnis zu behalten.
%T@gibt Ihnen die Änderungszeit wie ein Unix-Zeitstempel, sort -nsortiert numerisch, tail -1nimmt die letzte Zeile (höchster Zeitstempel) und cut -f2 -d" "schneidet das erste Feld (den Zeitstempel) von der Ausgabe ab.
Bearbeiten: Genau wie -printfes wahrscheinlich nur GNU ist, ist auch Ajreals Verwendung von stat -c. Obwohl es möglich ist, dasselbe mit BSD zu tun, sind die Formatierungsoptionen unterschiedlich (wie -f "%m %N"es scheint).
Und ich habe den Teil des Plural verpasst; Wenn Sie mehr als die neueste Datei möchten , erhöhen Sie einfach das Argument tail.
sort -rn | head -3anstelle von wechseln sort -n | tail -3. Eine Version gibt die Dateien vom ältesten zum neuesten, während die andere vom neuesten zum ältesten wechselt.
sorterstellt /tmpnach Bedarf temporäre Dateien (in ), daher denke ich nicht, dass dies ein Problem ist.
-printf '%T@ %Tb %Td %TY %p\n'geben Ihnen einen Datumsstempel (falls erforderlich) (ähnlich ls)
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
Nach der Antwort von @ plundra finden Sie hier die BSD- und OS X-Version:
find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "
findUnterstützt das BSD / OS X +statt \;? Denn das macht dasselbe (mehrere Dateien als Parameter übergeben), ohne die -print0 | xargs -0Pipe.
head -1zuhead -5
Anstatt die Ergebnisse zu sortieren und nur die zuletzt geänderten beizubehalten, können Sie mit awk nur das Ergebnis mit der größten Änderungszeit (in Unix-Zeit) drucken:
find . -type f -printf "%T@\0%p\0" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\0'
Dies sollte ein schnellerer Weg sein, um Ihr Problem zu lösen, wenn die Anzahl der Dateien groß genug ist.
Ich habe das NUL-Zeichen (dh '\ 0') verwendet, da ein Dateiname theoretisch jedes beliebige Zeichen (einschließlich Leerzeichen und Zeilenumbruch) enthalten kann.
Wenn Sie keine solchen pathologischen Dateinamen in Ihrem System haben, können Sie auch das Zeilenumbruchzeichen verwenden:
find . -type f -printf "%T@\n%p\n" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\n'
Darüber hinaus funktioniert dies auch in Mawk.
mawkder Debian-Standardalternative.
Ich hatte Probleme, die zuletzt geänderte Datei unter Solaris 10 zu finden. Es findgibt keine printfOption und sie statist nicht verfügbar. Ich habe die folgende Lösung gefunden, die für mich gut funktioniert:
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1
Um auch den Dateinamen anzuzeigen, verwenden Sie
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1
Erläuterung
find . -type f findet und listet alle Dateien aufsed 's/.*/"&"/' Umschließt den Pfadnamen in Anführungszeichen, um Leerzeichen zu verarbeitenxargs ls -EWenn der angegebene Pfad an gesendet wird, lsstellt die -EOption sicher, dass ein vollständiger Zeitstempel (Format Jahr-Monat-Tag Stunde-Minute-Sekunden-Nanosekunden ) zurückgegeben wirdawk '{ print $6," ",$7 }' extrahiert nur Datum und Uhrzeitawk '{ print $6," ",$7," ",$9 }' extrahiert Datum, Uhrzeit und Dateinamensort Gibt die nach Datum sortierten Dateien zurücktail -1 Gibt nur die zuletzt geänderte Datei zurückDies scheint auch mit Unterverzeichnissen gut zu funktionieren:
find . -type f | xargs ls -ltr | tail -n 1
Bei zu vielen Dateien verfeinern Sie den Fund.
-lOption zu lserscheint unnötig. Scheint einfach -trausreichend.
find . -type f -print0 | xargs -0 ls -ltr | tail -n 1
Zeigt die neueste Datei mit lesbarem Zeitstempel an:
find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1
Ergebnis sieht so aus:
2015-10-06 11:30: +0200 ./foo/bar.txt
Um mehr Dateien anzuzeigen, ersetzen Sie diese -n1durch eine höhere Nummer
Ich verwende ständig etwas Ähnliches sowie die Top-K-Liste der zuletzt geänderten Dateien. Bei großen Verzeichnisbäumen kann es viel schneller sein, eine Sortierung zu vermeiden . Im Fall der zuletzt geänderten Top-1-Datei:
find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'
In einem Verzeichnis mit 1,7 Millionen Dateien erhalte ich das neueste in 3.4s, eine Beschleunigung von 7.5x gegenüber der 25.5s-Lösung mit sort.
lastfile) und dann mit dem Ergebnis tun, was Sie möchten, z. B. ls -l $(lastfile .)oder open $(lastfile .)(auf einem Mac) usw.
Unter Ubuntu 13 funktioniert dies im Folgenden möglicherweise etwas schneller, da die Sortierung umgekehrt wird und "Kopf" anstelle von "Schwanz" verwendet wird, wodurch die Arbeit reduziert wird. So zeigen Sie die 11 neuesten Dateien in einem Baum an:
finden . -Typ f -printf '% T @% p \ n' | sort -n -r | Kopf -11 | cut -f2- -d "" | sed -e 's, ^. / ,,' | xargs ls -U -l
Dies ergibt eine vollständige ls-Liste ohne erneutes Sortieren und lässt das nervige './' weg, das 'find' auf jeden Dateinamen setzt.
Oder als Bash-Funktion:
treecent () {
local numl
if [[ 0 -eq $# ]] ; then
numl=11 # Or whatever default you want.
else
numl=$1
fi
find . -type f -printf '%T@ %p\n' | sort -n -r | head -${numl} | cut -f2- -d" " | sed -e 's,^\./,,' | xargs ls -U -l
}
Der größte Teil der Arbeit wurde jedoch mit der ursprünglichen Lösung von plundra erledigt. Danke plundra.
Ich stand vor dem gleichen Problem. Ich muss die neueste Datei rekursiv finden. Die Suche dauerte ungefähr 50 Minuten.
Hier ist ein kleines Skript, um es schneller zu machen:
#!/bin/sh
CURRENT_DIR='.'
zob () {
FILE=$(ls -Art1 ${CURRENT_DIR} | tail -n 1)
if [ ! -f ${FILE} ]; then
CURRENT_DIR="${CURRENT_DIR}/${FILE}"
zob
fi
echo $FILE
exit
}
zob
Es ist eine rekursive Funktion, die das zuletzt geänderte Element eines Verzeichnisses abruft. Wenn es sich bei diesem Element um ein Verzeichnis handelt, wird die Funktion rekursiv aufgerufen und in diesem Verzeichnis usw. gesucht.
Ich finde folgendes kürzer und mit besser interpretierbarer Ausgabe:
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
Angesichts der festen Länge der standardisierten Datumszeiten im ISO-Format ist die lexikografische Sortierung in Ordnung und wir benötigen keine -nOption für die Sortierung.
Wenn Sie die Zeitstempel wieder entfernen möchten, können Sie Folgendes verwenden:
find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '
Wenn das Ausführen statjeder einzelnen Datei zu langsam ist, können Sie die xargsDinge etwas beschleunigen:
find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" "
Dadurch wird die Änderungszeit aller Verzeichnisse im aktuellen Verzeichnis rekursiv in die neueste Datei in jedem Verzeichnis geändert:
for dir in */; do find $dir -type f -printf '%T@ "%p"\n' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done
Diese einfache Cli wird auch funktionieren:
ls -1t | head -1
Sie können -1 in die Anzahl der Dateien ändern, die Sie auflisten möchten
Ich fand den obigen Befehl nützlich, aber für meinen Fall musste ich auch das Datum und die Uhrzeit der Datei sehen. Ich hatte ein Problem mit mehreren Dateien, deren Namen Leerzeichen enthalten. Hier ist meine Arbeitslösung.
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " | sed 's/.*/"&"/' | xargs ls -l
$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10
Behandelt Leerzeichen in Dateinamen gut - nicht, dass diese verwendet werden sollten!
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 in find Hülle und Fülle folgen Sie dem Link.
So suchen Sie nach Dateien in / target_directory und allen Unterverzeichnissen, die in den letzten 60 Minuten geändert wurden:
$ find /target_directory -type f -mmin -60
So finden Sie die zuletzt geänderten Dateien in umgekehrter Reihenfolge der Aktualisierungszeit (dh zuerst die zuletzt aktualisierten Dateien):
$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r
Ich bevorzuge dieses, es ist kürzer:
find . -type f -print0|xargs -0 ls -drt|tail -n 1
Ich habe ein Pypi / Github-Paket für diese Frage geschrieben, weil ich auch eine Lösung brauchte.
https://github.com/bucknerns/logtail
Installieren:
pip install logtail
Verwendung: Schwänze geänderte Dateien
logtail <log dir> [<glob match: default=*.log>]
Verwendung2: Öffnet die zuletzt geänderte Datei im Editor
editlatest <log dir> [<glob match: default=*.log>]