it-swarm.com.de

Sortieren Sie die Ausgabe von find -exec ls

Ist es möglich, die Ausgabe von find … -exec ls -ls ; alpabetisch nach Dateinamen sortiert?

Dies ist mein Cron-Befehl:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

Dieser Befehl funktioniert größtenteils einwandfrei. Die Ergebnisse sind jedoch nicht in einer sinnvollen Reihenfolge sortiert. Es wäre sehr hilfreich, wenn sie nach dem Dateinamenfeld sortiert würden.

14
MaJ

Ich gehe davon aus, dass Ihre Dateinamen keine Zeilenumbrüche enthalten.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

Die Verwendung von + Anstelle von ; Zum Beenden der Aktion -exec Beschleunigt das Stapeln der Aufrufe von ls. Sie können sortieren, indem Sie den Befehl sort durchlaufen. Sagen Sie ihm, er soll beim 10. Feld mit dem Sortieren beginnen (die ersten 9 sind die Metadaten: Blöcke, Berechtigungen, Anzahl der Links, Benutzer, Gruppe, Größe und 3 Datums-/Zeitfelder). Die Option -n Weist ls an, numerische Werte für Benutzer und Gruppe zu verwenden, wodurch das Risiko vermieden wird, dass Benutzer- oder Gruppennamen Leerzeichen enthalten.

Alternativ können Sie mit zsh ohne Annahme eines beliebigen Namens davonkommen, indem Sie glob qualifiers verwenden, um die Dateien zu sammeln und zu sortieren, und zargs , um ls mehrmals in der Befehlszeile auszuführen wäre zu lang. Sie benötigen GNU ls (insbesondere die Option -f), Um eine erneute Sortierung nach ls zu vermeiden (ein anderer Ansatz wäre, ls mit zshs zstat zu emulieren ).

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf

POSIX hat Folgendes über Daten in einer ls-l Ong-Liste zu sagen:

Das Feld <date and time> Muss das entsprechende Datum und den Zeitstempel für die letzte Änderung der Datei enthalten. Im POSIX-Gebietsschema muss das Feld der Ausgabe des folgenden Datumsbefehls entsprechen:

date "+%b %e %H:%M"

... wenn die Datei in den letzten sechs Monaten geändert wurde oder:

date "+%b %e %Y"

Wenn Sie dies berücksichtigen und sicherstellen, dass Zeilenumbrüche in einem Dateinamen ordnungsgemäß mit der ebenfalls von POSIX angegebenen Option ls -q Überlagert werden, ist es relativ einfach, einen regulären Ausdruck für ein ls -Ergebnis vorzubereiten ohne find überhaupt:

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

grep dafür und Sie werden nur Zeilen zurückgeben, die die Zeichenfolgen enthalten, die entweder das heutige oder das gestrige Datum darstellen. Der folgende Befehl fügt dem ein wenig hinzu:

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls Optionen bestehen aus:

  1. -a Gibt alle Dateien in einem Verzeichnis zurück - einschließlich derjenigen, die mit einem .dot Beginnen.
  2. -l Lange Auflistung
  3. -R Listet rekursiv alle untergeordneten Verzeichnisse auf
  4. -c Zeigt die Änderungszeit anstelle der Zugriffszeit an
  5. -q Gibt den Shell-Glob ? Statt nicht druckbarer oder \t Ab-Zeichen in einem Dateinamen zurück

Diese Ergebnisse werden über die Datei |pipe An sed übergeben, die nur übereinstimmt:

  1. Die leere Zeile vor einem Pfadnamen und die folgende Zeile
  2. Zeilen, die mit - beginnen (mit anderen Worten - nicht d für Verzeichnis) , die auch Ihr date.
  3. Die Pfadnamenzeilen werden jedoch nicht gedruckt, es sei denn, das Verzeichnis, nach dem sie benannt sind, enthält tatsächlich Dateien, nach denen Sie gefiltert haben.

Die Ausgabe sieht folgendermaßen aus:

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

Ja, es funktioniert sogar mit LS_COLORS - was wahrscheinlich eine niedrige Priorität für Ihr cron ist, aber hey, Ihre Optionen sind offen.

In jedem Fall bietet dies einige wesentliche Vorteile gegenüber einigen anderen möglichen Lösungen.

  1. Erstens beinhaltet find + ls mehrere Aufrufe - dies beinhaltet nur einen einzigen ls Prozess, und deshalb ist es in der Lage, alles zuverlässig zu sortieren - was es tut Standard - und so wird sort auch als Zusatz gemacht.

  2. Jede Lösung, die find und sort und ls beinhaltet, erledigt die gesamte Arbeit zweimal . ls und find lösen beide jeden Pfadnamen und stat jede Datei auf. ls und sort sortieren beide Ergebnisse. Es ist wahrscheinlich am besten, stattdessen nur das einzelne ls zu verwenden.

  3. Dann gibt es natürlich die Teile date und sed dieser Antwort. Was dabei zu beachten ist, ist, dass Sie den schwierigen Teil erledigen und den regulären Ausdruck zuerst - und nur einmal - erhalten. Anschließend beschneiden Sie nur eine einzelne Liste von Ergebnissen, anstatt zu sagen, Ergebnisse zu erhalten, Ergebnisse zu erhalten, Ergebnisse zu sortieren und Ergebnisse zu sortieren.

  4. Dies gilt nicht für Dateinamen, die Zeilenumbrüche enthalten, wie dies bei anderen Lösungen wahrscheinlich der Fall ist. Diese Lösung hat ihre eigenen Einschränkungen - die ich als nächstes erläutere -, aber sie sind winzig und einfach zu handhaben. Meiner Meinung nach ist dies hier die robusteste Lösung.

Es gibt zwei Fälle, in denen der obige Befehl Probleme verursachen kann. Das erste betrifft die ? - Globs in den Dateinamen - obwohl es sich bereits um eine robustere Lösung als jede andere hier angebotene handelt und die Wahrscheinlichkeit, dass Sie überhaupt auf einen ? Stoßen, gering genug ist Für sich genommen besteht die Möglichkeit, dass das Auflösen dieser Globs mit mehr als einem Dateinamen übereinstimmt. Weitere Informationen zu diesem Thema finden Sie unter this .

Die andere Möglichkeit beinhaltet ein falsches Positiv - zum Beispiel, wenn Sie einen Dateinamen haben, der tatsächlich mit der Zeichenfolge date übereinstimmt, nach der wir mit grep suchen, die jedoch an keinem dieser Tage tatsächlich geändert wurde. Ich rechne nicht damit, dass dies ein Problem ist, aber wenn ja, fragen Sie danach und ich kann Ihnen wahrscheinlich helfen, die Regex spezifischer zu gestalten, um damit umzugehen.

1
mikeserv

Warum nicht das Ergebnis von find through sort weiterleiten und dann ls für jede der Zeilen ausführen?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done
1
groxxda

Sie können tatsächlich eine Kombination aus find, xargs und ls verwenden.

Hier ist ein Beispielbefehl: find . -type f -print0 | xargs -0 ls -lt

  • find sucht rekursiv nach allen Dateien im aktuellen Verzeichnis.
  • xargs übergibt diese Dateiliste in einem einzigen Aufruf an den Befehl ls (vorausgesetzt, find gibt weniger als ARG_MAX Dateien zurück).
  • ls -lt Sortiert diese Dateien nach Zeit und formatiert die Ausgabe

Um Ihr System ARG_MAX Abzurufen, können Sie Folgendes eingeben:

$ getconf ARG_MAX
> 2621440
0
Max