Suchen Sie Dateien in der Reihenfolge des Zeitstempels

Suchen Sie Dateien in der Reihenfolge des Zeitstempels

dirhat zwei reguläre Dateien.

file1hat abc\n, file2hat def\n. Komprimieren Sie diese beiden Dateien mit gzip, wie unten gezeigt,

#ls
#echo 'abc\n' > file1
#echo 'def\n' > file2
#gzip file1
#gzip file2
#ls
file1.gz  file2.gz

Nachdem ich den Inhalt überprüft habe,

#find . -type f  -name "*.gz" -exec zgrep -Iq . \{} \; -exec zcat \{} \;
def\n
abc\n

Ich erhalte den Inhalt der Dateien nicht in der Reihenfolge ihrer Erstellungszeit. Die erwartete Ausgabe sollte immer sein abc\ndef\n.

Interessante Beobachtung: Die tatsächliche Ausgabe ist manchmal def\nabc\nund manchmalabc\ndef\n

Frage:

Wie findet man Dateien in der Reihenfolge (abnehmend/aufsteigend) des Zeitstempels?

Antwort1

Die Reihenfolge der von gemeldeten Dateien findist für den Benutzer undurchsichtig. Es kann die Reihenfolge sein, in der sie im Verzeichnis erscheinen. Einige findImplementierungen sortieren sie nach Inode-Nummer oder anderen Kriterien neu, um die Leistung zu verbessern. Die einzige Möglichkeit, die Reihenfolge zu ändern, besteht über das -depthPrädikat, finddas Process/Output anweist, vor dem Zweig zu gehen, auf dem sie sich befinden.

Als Alternative zu können Sie die rekursive Glob-Funktion von findverwenden :zsh

zgrep whatever ./**/*.gz(D.Om)

Der OmGlob-Qualifizierer dient zum Sortieren nach der Zeit der letzten Änderung (älteste zuerst). .gilt nur für reguläre Dateien (entspricht find's -type f), Dschließt versteckte (Punkt-)Dateien ein, wie findes standardmäßig der Fall wäre.

Wenn Sie eineArgumentliste zu langFehler, Sie können Folgendes verwenden zargs:

autoload -U zargs # best in ~/.zshrc
zargs ./**/*.gz(D.Om) -- zgrep whatever

Mit bash(oder jeder Shell, die Prozessersetzung im Ksh-Stil unterstützt) und aktuellen GNU-Tools wäre das Äquivalent:

xargs -r0a <(
  export LC_ALL=C
  find . -type f -name '*.gz' -printf '%T@\t%p\0' |
    sort -zn | cut -zf2-) zgrep whatever

Antwort2

Eine Möglichkeit besteht darin, den Zeitstempel der Datei zusammen mit dem Dateipfad auszugeben, danach zu sortieren und ihn dann zu entfernen:

find -type f -name "*.gz" -printf '%C@\t%p\n'|sort -nk1|cut -f2-|xargs zcat 

Beachten Sie, dass wenn Ihre Dateinamen möglicherweise unsichere Zeichen (wie Leerzeichen) enthalten können, ersetzen Sie einfach

xargs zcat 

mit

xargs -d "\n" zcat 

und wenn Sie die Zeilenumbrüche in den Dateinamen berücksichtigen müssen, können Sie zum Beenden von Datensätzen ein Nullbyte verwenden, wie in der Antwort von @stéphane-chazela beschrieben (obwohl dies in der Praxis selten ein Problem darstellt).

Antwort3

Leider funktioniert der Find-Befehl so, dass die Ausgabe nicht unbedingt alphabetisch oder nach Dateialter sortiert ist. Sie könnten etwas wie Folgendes versuchen:

ls -1dtr $(find . -maxdepth 1 -type f -name '*.gz') | xargs gzcat $1

verwandte Informationen