Ich habe Verzeichnisse, deren Namen Zeitstempel sind, angegeben in Millisekunden seit dem 01.01.1970:
1439715011728
1439793321429
1439879712214
.
.
Und ich brauche eine Ausgabe wie:
1442039711 Sat Sep 12 08:35:11 CEST 2015
1442134211 Sun Sep 13 10:50:11 CEST 2015
1442212521 Mon Sep 14 08:35:21 CEST 2015
.
.
Ich kann alle Verzeichnisse mit folgendem Befehl auflisten:
find ./ -type d | cut -c 3-12
Aber ich kann die Ausgabe nicht auf den nächsten Befehl setzen: date -d @xxxxxx
und die Ausgabe manipulieren.
Wie kann ich das machen?
Fri Oct 2 05:35:28 47592
)Antworten:
Sie sind auf dem richtigen Weg (für eine einfachere Lösung, die nur 2 oder 3 Befehle ausführt, siehe unten). Sie sollten
*
statt verwenden./
, um das aktuelle Verzeichnis loszuwerden¹ und dies vereinfacht das Schneiden der Millisekunden etwas, dann leiten Sie das Ergebnis einfach in GNUparallel
oderxargs
²:bekommen
und um den Sekundenversatz davor zu addieren, wie Ihr Beispiel zeigt:
oder:
bekommen:
Es ist jedoch einfacher zu tun³:
Dadurch erhalten Sie erneut die gleiche angeforderte Ausgabe.
Der Nachteil bei der Verwendung
*
ist, dass Sie für die Erweiterung auf Ihre Befehlszeile beschränkt sind. Der Vorteil ist jedoch, dass Sie Ihre Verzeichnisse nach dem Zeitstempelwert sortiert bekommen. Wenn die Anzahl der Verzeichnisse ein Problem ist, verwenden Sie-mindepth 1
, aber verlieren Sie die Reihenfolge:und
sort
bei Bedarf einfügen :¹ Dies setzt voraus, dass keine verschachtelten Unterverzeichnisse vorhanden sind, wie dies in Ihrem Beispiel der Fall zu sein scheint. Sie können auch verwenden ,
./ -mindepth 1
statt*
² Sie können ersetzen
parallel
mitxargs -I{}
hier als @hobbs und @don_crissti vorgeschlagen, es ist nur ausführlicher. ³ basierend auf der Antwort von Gilles zur Verwendung derdate
Dateilesefunktionenquelle
xargs
wenn Sie nicht habenparallel
, was viele Leute wahrscheinlich nicht tun.xargs
hat nicht die Möglichkeit zu geben , wo das Argument wie gehtparallel
hat mit{}
.find ./ -type d | cut -c 3-12 | xargs -I{} date --d @{} +'%Y-%m-%d'
-I
Option verwenden.--d
oder--da
würde mit aktuellen Versionen von GNUdate
funktionieren, könnte aber aufhören zu funktionieren. Der Tagdate
führt eine--dalek
Option ein (für Daten im Dalek-Kalender).Ich würde vermeiden, mehrere Befehle pro Datei in einer Schleife auszuführen. Da Sie bereits GNUisms verwenden:
Womit nur zwei Befehle ausgeführt werden.
strftime()
ist GNU-spezifisch, wiedate -d
.quelle
Du hast bereits:
Damit erhalten Sie vermutlich die Zeitstempel im Epochenformat. Fügen Sie nun eine while-Schleife hinzu:
Beachten Sie jedoch, dass diese Syntax in einigen Shells die while-Schleife in einer Subshell abruft. Wenn Sie also versuchen, eine Variable dort festzulegen, wird sie nicht sichtbar, sobald Sie die Schleife verlassen haben. Um das zu beheben, müssen Sie die Dinge leicht auf den Kopf stellen:
Das versetzt die
find
in die Subshell und hält die while-Schleife in der Mainshell. Das Syntax (AT & Tksh
,zsh
undbash
spezifisch) ist nur erforderlich , wenn Sie ein Ergebnis aus dem Innern der Schleife wieder zu verwenden suchen, though.quelle
done <(find)
stattdone < <(find)
, es war richtig füryash
(wo<(...)
ist die Prozess Umleitung, keine Prozess Substitution), so meine bearbeiten ein bisschen Kavalier war , wie es die Schale gewesen sein könnte, dass für gemeint.Wenn Sie GNU-Datum haben, kann es Datumsangaben konvertieren, die aus einer Eingabedatei gelesen wurden. Sie müssen nur die Zeitstempel ein wenig massieren, damit sie erkannt werden. Der Eingabesyntax für einen Zeitstempel, der auf der Unix-Epoche basiert,
@
folgt die Anzahl der Sekunden, die einen Dezimalpunkt enthalten können.quelle
date
Lesen s-Dateien. Dies ergibt sichdate: invalid date ‘@’
aufgrund der Übersetzung des aktuellen Verzeichnisses (./
). Und da Sie die Millisekunden wegwerfen können, können Sie die zweitesed
Bearbeitung vereinfachen, indem Sie nur die letzten 3 Zeichen ablegen. Oder entfernen Sie alles und verwenden Siefind * -type d -printf "@%.10f" | date ...
Ich würde es perlish tun - füttere eine Liste von Zeitstempeln:
Dies gibt aus:
Wenn Sie ein bestimmtes Ausgabeformat wünschen, können Sie
strftime
zB verwenden:Welche, um dies in einen Einzeiler in Ihrer Pfeife zu verwandeln:
Aber ich würde wahrscheinlich vorschlagen, stattdessen das
File::Find
Modul zu verwenden und das Ganze in Perl zu machen. Wenn Sie vor dem Ausschneiden ein Beispiel für Ihre Verzeichnisstruktur angeben, gebe ich Ihnen ein Beispiel. Aber es wäre so etwas wie:quelle
Mit
zsh
und in der Strftime eingebaut:Dies setzt voraus, dass alle Ihre Verzeichnisnamen im aktuellen Verzeichnis tatsächlich Epochen sind.
Weiteres Filtern / Verarbeiten ist möglich, vorausgesetzt Sie legen fest, wie diese Zahlen in Ihrem Beispiel verarbeitet werden sollen (sie ähneln eher den Epochenzeiten, die den Geburtsdaten von Prinzessin Leia und Luke Skywalker entsprechen ...), z. B. suchen Sie rekursiv nach Verzeichnisnamen, die mindestens übereinstimmen 10 Stellen und berechnen Sie das Datum anhand der ersten 10 Stellen:
quelle
Verwenden von GNU Parallel:
Wenn Sie statt Leerzeichen \ t akzeptieren können:
quelle
parallel
in geschrieben istperl
. Dies scheint übertrieben, wenn man bedenkt, dassperl
es einenstrftime()
Operator gibt. Likeperl -MPOSIX -lpe '$_.=strftime(" %c", localtime substr $_, 2, 10)'
parallel
. IMOparallel
ist ein großartiges Tool zur Parallelisierung von CPU-intensiven Aufgaben, das jedoch für diese Art von Aufgaben hier nicht geeignet ist.Normalerweise kann der Befehl find mit jedem Befehl verknüpft werden, der verwendet
exec
Arguments .In Ihrem Fall können Sie folgendermaßen vorgehen:
quelle
Verwenden von Python (es ist möglicherweise die langsamere Lösung)
gibt:
quelle