Frage

Ich habe eine Suche um hatte, und aus meiner Sicht mit Backticks ist die einzige Art, wie ich dieses Problem lösen kann. Ich versuche, für jede Datei in einem Verzeichnis des mdls Befehl von Perl zu nennen es der letzten griffenen Zeit zu finden. Das Problem, das ich habe, ist, dass in den Dateinamen ich von find habe ich unescaped Räume haben, die offensichtlich bash nicht wie. Gibt es eine einfache Möglichkeit, alle weißen Raumes in meinem Dateinamen zu entkommen, bevor sie zu mdls vorbei. Bitte verzeihen Sie mir, wenn dies eine offensichtliche Frage. Ich bin ganz neu in Perl.

my $top_dir = '/Volumes/hydrogen/FLAC';

sub wanted { # Learn about sub routines 
    if ($File::Find::name) { 
         my $curr_file_path = $File::Find::name. "\n";
        `mdls $curr_file_path`;
         print $_;
    }
}

find(\&wanted, $top_dir);
War es hilfreich?

Lösung

Wenn Sie sicher sind, dass die Dateinamen enthalten keine Zeilenumbrüche (entweder CR oder LF), dann so ziemlich alle Unix-Shells akzeptieren Backslash zitieren, und Perl hat die quotemeta Funktion, sie anzuwenden.

my $curr_file_path = quotemeta($File::Find::name);
my $time = `mdls $curr_file_path`;

Leider das nicht funktioniert für Dateinamen mit Zeilenumbrüchen, da die Schalengriffe ein Backslash durch eine neue Zeile, gefolgt von Löschen von beide Zeichen, anstatt nur den umgekehrten Schrägstrich. Also, um wirklich sicher, verwenden String :: ShellQuote :

use String::ShellQuote;
...
my $curr_file_path = shell_quote($File::Find::name);
my $time = `mdls $curr_file_path`;

Das sollte auf Dateinamen arbeitet nichts außer einem NUL-Zeichen enthalten, die Sie sollten wirklich nicht in Dateinamen verwendet werden.

Beide Lösungen sind für Unix-Shells nur. Wenn Sie unter Windows sind unter Angabe richtige Schale ist viel schwieriger.

Andere Tipps

Wenn Sie gerade „letzte Zugriffszeit“ in Bezug auf dem von den OS letzte Zugriffszeit zu wollen, ist mdls das falsche Werkzeug. Verwenden Sie Perl stat. Wenn Sie letzte Zugriffszeit in Bezug auf der Mac registrierten Anwendung mögen (dh, ein Lied von Quicktime oder iTunes) dann mdls ist möglicherweise das richtige Werkzeug. (Sie könnten nutzen auch osascript den Mac App direkt abfragen ...)

Backticks sind für den Text Rückkehr zu erfassen. Da Sie mdls verwenden, nehme ich an die Erfassung und den Text Parsen noch kommen.

So gibt es mehrere Methoden:

  1. Verwenden Sie die Liste Form System und die Angabe ist nicht erforderlich ( wenn du nicht über die Rückkehr Text Pflege);

  2. Verwenden Sie String :: ShellQuote die Dateinamen zu entkommen, bevor sh zu senden;

  3. Erstellen Sie die Zeichenfolge aus und legt in einfachen Anführungszeichen vor dem Senden an die Schale zu senden. Das ist schwieriger als es klingt, weil Dateinamen mit einfachen Anführungszeichen besiegt Ihre Angebote! Zum Beispiel ist sam's song.mp4 ein juristischer Dateiname, aber wenn Sie mit einfachen Anführungszeichen umgeben bekommen Sie 'sam's song.mp4' was nicht, was Du gemeint ...

  4. Mit open ein Rohr mit dem Ausgang des Kindes Prozess wie diesem zu öffnen: open my $fh, '-|', "mdls", "$curr_file" or die "$!";

Beispiel String :: ShellQuote:

use strict; use warnings;
use String::ShellQuote;
use File::Find;

my $top_dir = '/Users/andrew/music/iTunes/iTunes Music/Music';

sub wanted { 
    if ($File::Find::name) { 
         my $curr_file = "$File::Find::name";
         my $rtr;
         return if -d;
         my $exec="mdls ".shell_quote($curr_file);
         $rtr=`$exec`;  
         print "$rtr\n\n";
    }
}

find(\&wanted, $top_dir);

Beispiel Rohre:

use strict; use warnings;
use String::ShellQuote;
use File::Find;

my $top_dir = '/Users/andrew/music/iTunes/iTunes Music/Music';

sub wanted { 
    if ($File::Find::name) { 
         my $curr_file = "$File::Find::name";
         my $rtr;
         return if -d;
         open my $fh, '-|', "mdls", "$curr_file" or die "$!";
         { local $/; $rtr=<$fh>; }  
         close $fh or die "$!";
         print "$rtr\n\n";
    }
}

find(\&wanted, $top_dir);

Wenn Sie nur die letzte Zugriffszeit finden wollen, gibt es einige seltsame Mac Grund nicht stat verwenden? Wann würde es schlimmer als kMDItemLastUsedDate sein?

 my $last_access = ( stat($file) )[8];

Es scheint kMDItemLastUsedDate ist nicht immer auf die letzte Zugriffszeit aktualisiert. Wenn Sie mit einer Datei durch das Terminal (z cat, more) arbeiten, ändert kMDItemLastUsedDate nicht aber der Wert, der wieder von stat kommt, ist richtig. touch erscheint das Richtige in beiden Fällen zu tun.

Es sieht aus wie Sie für die richtige Antwort stat brauchen, aber mdls, wenn Sie für den Zugriff durch Anwendungen suchen.

Sie können Bypass die Shell durch den Befehl als eine Liste zum Ausdruck, kombiniert mit capture() von IPC :: System :: Simple :

use IPC::System::Simple qw(capture);

my $output = capture('mdls', $curr_file_path);

Quote der Variablennamen in den Backticks:

`mdls "$curr_file_path"`;
`mdls '$curr_file_path'`;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top