Der Finder in Mac OS X 10.7 Lion zeigt ein neues Stück Datei-Metadaten, „Datum hinzugefügt“, das das Datum verfolgt, an dem ein Element zu einem Ordner hinzugefügt wurde. Nach dem Upgrade auf 10.7 hat keines der Elemente in meinem ~/Downloads
Ordner "Hinzugefügt"-Werte. Ich möchte alle leeren „Hinzugefügt-Datum“-Werte so einstellen, dass sie mit den „Änderungsdatum“-Werten übereinstimmen, aber ich kann nicht herausfinden, wie ich das „Hinzugefügt-Datum“-Attribut auf einen bestimmten Wert festlegen kann.
Meine erste Vermutung war folgende:
xattr -w com.apple.metadata:kMDItemDateAdded "2012-02-19 16:34:47 +0000" myfile
Aber das scheint nicht zu funktionieren (obwohl es auch keinen Fehler meldet).
OK, neuer Ansatz hier. Achtung: Ich habe kein System, das auf Lion aktualisiert wurde (auf meinem Computer war Lion installiert), daher kann ich dies nicht testen. Ungetesteter Code; Sichern Sie, bevor Sie diesen Code ausprobieren!
Meine vorherige Antwort basierte auf der Sortierreihenfolge, die vom Download-Stapel im Dock verwendet wurde. Das Feld "Datum hinzugefügt" im Finder scheint auf Spotlight-Informationen zu basieren, die schwer zu hacken sind. Es ist auch nicht über AppleScript zugänglich. Aber es scheint einen Workaround zu geben.
Erstellen Sie einen neuen Workflow in Automator.
Stellen Sie den Arbeitsablauf so ein, dass er Dateien oder Ordner aus dem Finder akzeptiert, indem Sie die Aktion „Nach Finder-Objekten fragen“ hinzufügen.
Lassen Sie den Workflow ein AppleScript ausführen, indem Sie die Aktion „AppleScript ausführen“ hinzufügen.
Verwenden Sie dieses AppleScript:
on run {input, parameters}
do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime Off" with administrator privileges
tell application "Finder"
repeat with x in input
set myfile to POSIX path of x
set nm to name of x
set d to modification date of x
set yr to (character 3 of (year of d as string)) & (character 4 of (year of d as string))
set mth to (month of d as number) as string
if length of mth is 1 then set mth to "0" & mth
set dy to day of d as string
if length of dy is 1 then set dy to "0" & dy
set h to hours of d as string
if length of h is 1 then set h to "0" & h
set m to minutes of d as string
if length of m is 1 then set m to "0" & m
set s to seconds of d as string
if length of s is 1 then set s to "0" & s
set dt to mth & ":" & dy & ":" & yr as string
set tm to h & ":" & m & ":" & s as string
do shell script "sudo /usr/sbin/systemsetup -setdate '" & dt & "'" with administrator privileges
do shell script "sudo /usr/sbin/systemsetup -settime '" & tm & "'" with administrator privileges
do shell script "mv \"" & myfile & "\" /var/tmp/clobber"
do shell script "mv /var/tmp/clobber \"" & myfile & "\""
end repeat
end tell
do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime On" with administrator privileges
return input
end run
Wählen Sie die Dateien aus, die noch kein Datum hinzugefügt haben (sortieren Sie im Finder nach Datum hinzugefügt, wählen Sie dann den Teil der Liste ohne Datum aus) und führen Sie diesen Dienst aus.
/.Spotlight-V100
ist, könnte dies so gut sein, wie es nur geht. Aber ich würde gerne eine saubere Antwort sehen.$
in ihrem Namen stand, aber ich habe das umgangen, indem ich diese Datei vorübergehend umbenannte. Damit das AppleScript mit solchen Dateien umgehen kann, deuten meine Suchen darauf hin, dass Sie sie durch ersetzen könnten myfile
, quoted form of myfile
aber ich habe das nicht getestet. Wenn man das versucht hat, ist es vielleicht übersichtlicher, das Anführungszeichen beim Setzen zu machen myfile
und die Variable in umzubenennen quotedFilePath
.Wenn ich xattr -l
Elemente in meinem Downloads-Ordner ausführe, erhalte ich ein Feld, das in etwa so aussieht:
com.apple.metadata:kMDItemDownloadedDate:
00000000 62 70 6C 69 73 74 30 30 A1 01 33 41 B4 83 4D BF |bplist00..3A..M.|
00000010 4C 4F E3 08 0A 00 00 00 00 00 00 01 01 00 00 00 |LO..............|
00000020 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 13 |.....|
00000035
Dies ist eine binäre Plist. Wenn ich HexFiend verwende, um eine Datei mit diesen Bytes zu erstellen (ja, ich habe sie manuell eingegeben; Explosion aus der Vergangenheit wie die Eingabe von Assembler-Code aus einer Zeitschrift in mein Apple ][GS), dann speichere ich sie als .plist-Datei, die ich geöffnet habe die Datei in TextWrangler und erhielt die folgende unkompilierte XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<date>2011-11-28T05:03:59Z</date>
</array>
</plist>
Das heißt, während Apple die Daten in kompiliertem XML zu speichern scheint, scheint Klartext zu funktionieren.
Mit anderen Worten, wenn Sie das Änderungsdatum der Datei in Zeichenfolgenform erhalten können, können Sie den Befehl ausführen xattr -w com.apple.metadata:kMDItemDownloadedDate "2012-02-19 16:34:47 +0000" file
, um das "heruntergeladene Datum" zu ändern, das das Feld zu sein scheint, nach dem tatsächlich sortiert wurde, nicht das tatsächliche Datum hinzugefügt.
Endlich haben Sie beim Hinzufügen des (unbenutzten) kMDItemDateAdded
Felds keinen Fehler erhalten, da, wie ich in diesem Artikel erfahren habe , xattr
gerne das gewünschte Metadatenfeld festgelegt wird, verwendet oder unbenutzt.
Das ist der Kern der Antwort. Ich werde daran arbeiten, ein AppleScript zu schreiben, um das Änderungsdatum für jede Datei zu erhalten, zu prüfen, ob kMDItemDownloadedDate
es gesetzt ist, und wenn nicht, setze kMDItemDownloadedDate auf das Änderungsdatum, aber ich wollte den Kern der Antwort veröffentlichen.
xattr -p com.apple.metadata:kMDItemDownloadedDate FILENAME_HERE | xxd -r -p | plutil -convert xml1 - -o -
. Die xxd konvertiert in binäre Plist-Daten, dann plutil
konvertiert die in XML-Plist und druckt sie.xattr -l
, und kMDItemDownloadedDate ist nicht in aufgeführt mdls
. Neugieriger und neugieriger. Auch das Feld „Datum hinzugefügt“ wird nicht in einem xattr für das Verzeichnis gespeichert . Wo befinden sich diese Metadaten?xattr
es sich um ein Python-Skript handelt, sollte es möglich sein, in diesem Skript herumzustöbern und herauszufinden, wie man die binären Daten des Attributs in binärer und nicht in hexadezimaler Form erhält, damit Sie sie direkt an plutil
.Ich kann keine Möglichkeit finden, das im Finder angezeigte "Datum hinzugefügt" einzustellen.
Ich glaube, Sie haben Recht, dass es aus dem kMDItemDateAdded
Metadatenattribut des Spotlight-Index abgerufen wird. Spotlight scheint dies jedoch auf irgendeine Weise selbst abzuleiten.
Ich habe versucht, ein erweitertes Dateiattribut einzurichten, das com.apple.metadata:kMDItemDateAdded
für einen Datumswert in einem von mehreren verschiedenen Formaten aufgerufen wird, einschließlich des von verwendeten Formats, kMDItemDateAdded
und keines davon wurde vom Spotlight-Index erfasst, dh unabhängig davon, welcher Wert von angezeigt wird xattr
, der Wert gezeigt durch mdls
wurde nicht geändert.
Ich würde vermuten , obwohl ich es nicht sicher weiß, dass Spotlight dieses Datum einfach basierend auf dem ersten Mal festlegt, wenn es eine Datei an einem bestimmten Ort indiziert, und keine anderen Metadaten überprüft, um es zu generieren. Wenn Sie mv
eine Datei aus den Downloads heraus und wieder hinein verschieben, wird das Datum hinzugefügt, an dem sie wieder hinein verschoben wurde, aber keine der Dateimetadaten scheint betroffen zu sein, nur die Spotlight-Metadaten.
Zusammenfassend gehe ich also davon aus, dass Date Added nur irgendwo in den ziemlich kryptischen Eingeweiden von /.Spotlight-V100 gespeichert ist, und wenn jemand keine Möglichkeit hat, Spotlight anzuweisen, einen Metadateneintrag auf einen beliebigen Wert zu aktualisieren, kann ich es tun. Ich sehe keine Möglichkeit, dies zu tun.
Danke an Daniel Lawson für die Lösung! Es funktioniert immer noch gut, auch zwei Jahre später.
Ich habe zwei Ergänzungen:
1) Bitte beachten Sie, dass der Code der akzeptierten Antwort einen kleinen Fehler enthält.
Diese Linie:
do shell script "/usr/sbin/systemsetup -settime ''" & tm & "'"
...hat einen zusätzlichen Apostroph, der einen "unerwarteten EOF"-Fehler auslöst. Es sollte lauten:
do shell script "/usr/sbin/systemsetup -settime '" & tm & "'"
2) Noch wichtiger, ab Mavericks 10.9.2 benötigt Systemsetup Administratorrechte. Daher sollte jeder Aufruf des Shell-Skripts dieser Formel folgen:
do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime Off" with administrator privileges
Hier ist die vollständig modifizierte Version des AppleScripts, die für 10.9.3 bestätigt wurde:
on run {input, parameters}
do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime Off" with administrator privileges
tell application "Finder"
repeat with x in input
set myfile to POSIX path of x
set nm to name of x
set d to modification date of x
set yr to (character 3 of (year of d as string)) & (character 4 of (year of d as string))
set mth to (month of d as number) as string
if length of mth is 1 then set mth to "0" & mth
set dy to day of d as string
if length of dy is 1 then set dy to "0" & dy
set h to hours of d as string
if length of h is 1 then set h to "0" & h
set m to minutes of d as string
if length of m is 1 then set m to "0" & m
set s to seconds of d as string
if length of s is 1 then set s to "0" & s
set dt to mth & ":" & dy & ":" & yr as string
set tm to h & ":" & m & ":" & s as string
do shell script "sudo /usr/sbin/systemsetup -setdate '" & dt & "'" with administrator privileges
do shell script "sudo /usr/sbin/systemsetup -settime '" & tm & "'" with administrator privileges
do shell script "mv \"" & myfile & "\" /var/tmp/clobber"
do shell script "mv /var/tmp/clobber \"" & myfile & "\""
end repeat
end tell
do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime On" with administrator privileges
return input
end run
Wenn Sie gerne etwas C-Code kompilieren, dann können diese Daten , wie von Ken Thomases hervorgehoben, aus abgerufengetattrlist(2)
werden . Und während es so klingt, als hätte das entsprechende settralist(2)
Datum für das hinzugefügte Datum auf älteren Versionen von macOS nicht funktioniert, funktioniert der folgende Code für mich auf macOS Monterey 12.5.1 und passt das im Finder angezeigte Datum an.
Es ist nur das Abrufen und Setzen des ATTR_CMN_ADDEDTIME
Attributs, das im Handbuch beschrieben wird
die Zeit, zu der das Dateisystemobjekt erstellt oder in sein enthaltendes Verzeichnis umbenannt wurde. Beachten Sie, dass inkonsistentes Verhalten beobachtet werden kann, wenn dieses Attribut für fest verknüpfte Elemente angefordert wird
#include <stdlib.h>
#include <string.h>
#include <sys/attr.h>
#include <unistd.h>
/*
* Get kMDItemDateAdded of path.
*
* Returns:
* • 0 on success
* • 1 if a system call failed: check errno
* • 2 if something else went wrong
*/
int get_date_added(const char* path, struct timespec * out) {
attrgroup_t request_attrs = ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_ADDEDTIME;
struct attrlist request;
memset(&request, 0, sizeof(request));
request.bitmapcount = ATTR_BIT_MAP_COUNT;
request.commonattr = request_attrs;
typedef struct {
u_int32_t length;
attribute_set_t returned;
struct timespec added;
} __attribute__((aligned(4), packed)) response_buf_t;
response_buf_t response;
int err = getattrlist(path, &request, &response, sizeof(response), 0);
if (err != 0) {
return 1;
}
if (response.length != sizeof(response)) {
// Need a different-sized buffer; but provided one of exactly required
// size?!
return 2;
}
if (response.returned.commonattr != request_attrs) {
// Didn’t get back all requested common attributes
return 2;
}
out->tv_sec = response.added.tv_sec;
out->tv_nsec = response.added.tv_nsec;
return 0;
}
/*
* Set kMDItemDateAdded of path.
*
* Returns:
* • 0 on success
* • 1 if a system call failed: check errno
*/
int set_date_added(const char* path, struct timespec in) {
attrgroup_t request_attrs = ATTR_CMN_ADDEDTIME;
struct attrlist request;
memset(&request, 0, sizeof(request));
request.bitmapcount = ATTR_BIT_MAP_COUNT;
request.commonattr = request_attrs;
typedef struct {
struct timespec added;
} __attribute__((aligned(4), packed)) request_buf_t;
request_buf_t request_buf;
request_buf.added.tv_sec = in.tv_sec;
request_buf.added.tv_nsec = in.tv_nsec;
int err = setattrlist(path, &request, &request_buf, sizeof(request_buf), 0);
if (err != 0) {
return 1;
}
return 0;
}
erotsppa
Johannes Syrakus