Ich habe ein Programm, das einige Dateien als Argumente in einer Befehlszeile aufnimmt. Ich möchte es mit allen Dateien in einem Verzeichnis aufrufen, das in umgekehrter Zeitreihenfolge aufgeführt ist.
Zum Beispiel:
Ich habe folgende Dateien in umgekehrter Zeitreihenfolge in einem Verzeichnis
$ ls -tr
Introduction.pdf 'Object-Oriented Data Model.pdf'
Ich kann mein Programm einfach ausführen,
myprogram Introduction.pdf 'Object-Oriented Data Model.pdf'
aber ich möchte die Dateiliste mit einem anderen Befehl machen. Dies funktioniert aufgrund des Leerzeichens im Namen einer Datei nicht:
myprogram $(ls -tr)
Ich erinnere mich, dass das Parsen der ls
Ausgabe keine gute Praxis ist. Ich bin mir nicht sicher, ob ich find
helfen kann.
Was kann ich dann tun?
Vielen Dank.
parsing ls
keine gute Praxis?ls -rt | myprogram
würde funktionieren, würde der Dateiname, wenn er ein Leerzeichen hat, einfachobject-oriented\ data\ model.pdf
einen Backslash vor jedem Leerzeichen verwenden. Oder wennmyprogram
es in C geschrieben ist, könnten Sie es verwenden.popen("ls -rt", "r")
Ich mache das die ganze Zeit und es funktioniert großartig.ls ... | myprogram
würde die Dateinamen zur Verfügung stellt (als Ausgang from` ls`) als stdin an das Programm, nicht als Argument, wie gewünscht. Beachten Sie auch, dass Dateinamen mit einer neuen Zeile als zwei separate Zeilen an das Programm gesendet werden, die sie nicht mehr von zwei separaten Dateinamen unterscheiden können.myprogram
? Ein Bash-Skript, csh / tcsh-Skript, ksh? oder ist es eine ausführbare Datei, die aus C-Code kompiliert wurde? oder Python, Java ...?Antworten:
Wenn Sie einigermaßen aktuelle Versionen der GNU-Dienstprogramme haben, können Sie diese mit NULL-terminierten Daten verarbeiten lassen. Auf diese Weise können Pipelines erstellt werden, die nicht von Leerzeichen oder Zeilenumbrüchen in den Daten selbst betroffen sind.
Mein Testwerkzeug ist ein schnelles Skript namens
/tmp/args
:Auf diese Weise können Sie eine Reihe von Dateinamen in der Befehlszeile eingeben, sortiert nach der zuletzt geänderten Dateizeit:
Der
find
Befehl stellt jedem Datei- / Pfadnamen eine Darstellung in Sekundenbruchteilen des Datums / der Uhrzeit vor, die zuletzt geändert wurde. Dies wird vonsort
der Reihenfolge vom niedrigsten (ältesten) zum höchsten (neuesten) gehandhabt . Diesed
Streifen von der führenden Nummer, nach der wir gerade sortiert haben, und der resultierende Satz von Dateinamen werden an übergebenxargs
. Ersetzen Sie das%p
durch,%P
wenn Sie die führenden./
Dateinamen weglassen möchten .Beispieldaten
Beispiel Ergebnis
quelle
Bash macht es noch nicht einfach, Dateien nach Änderungszeit zu sortieren. Hier ist die obligatorische zsh-basierte Antwort. Sie müssen nicht als Anmeldeshell zu zsh wechseln, um die Funktionen nutzen zu können.
Hier habe ich eine Wrapper-Funktion eingerichtet, die entweder ein oder zwei Argumente erwartet. das erste Argument ist das auszuführende Programm (zB
myprogram
); Das zweite optionale Argument ist das Verzeichnis mit den Dateien, die Sie an das Programm übergeben möchten. Wenn Sie kein zweites Argument angeben, wird standardmäßig das aktuelle Verzeichnis verwendet.Nennen Sie es natürlich wie Sie wollen. Nach einer kurzen Überprüfung des zweiten Arguments (standardmäßig
.
das aktuelle Verzeichnis) rufen wir zsh mit einer einzelnen Zeichenfolge in doppelten Anführungszeichen auf, die das Programm und einige Anfangsargumente (Argument 1) und das Verzeichnis (Argument #) enthält. 2) - standardmäßig.
- mit einer Wildcard / Glob-Erweiterung, die zwei "Glob-Qualifizierer" in der nachfolgenden Klammer enthält:.
- müssen reguläre Dateien sein (keine Verzeichnisse oder Symlinks usw.)om
-o
Sortieren Sie die resultierende Liste nach Änderungszeit, zuletzt zuerstEs ist dieses
om
Glob-Qualifikationsmerkmal, das die ganze eigentliche Arbeit hier erledigt.Hier sind einige Beispielläufe.
myprog
ist ein einfaches Shell-Skript, um die empfangenen Argumente in der folgenden Reihenfolge zu demonstrieren:und
go.sh
ist die Datei, in der ich die Funktion gespeichert habe. Der Rest der Verzeichnisstruktur lautet:... wo ich die Sätze von drei Dateien in jedem Unterverzeichnis in der aufgelisteten Reihenfolge erstellt habe; Ich erwarte, sie in derselben Reihenfolge zu sehen, wenn ich die Funktion ausführe. Der erste Dateiname unter dir3 enthält eine neue Zeile, dargestellt durch
tree
mit\012
. Die Ergebnisse sind:Demonstration des Verhaltens des Standardverzeichnisses im aktuellen Verzeichnis:
Normale Dateinamen-Demonstration
Das Verzeichnis enthält ein Leerzeichen
Dateinamen enthalten Leerzeichen
quelle
Angenommen, die Dateinamen enthalten keine Zeilenumbrüche.
Beispiel:
Variante für eine Standard-Shell, die keine
$'...'
Zeichenfolgen unterstützt:Einfacher Python-Wrapper, der auch mit Dateinamen funktioniert, die Zeilenumbrüche enthalten. Nutzung kann sein
this_wrapper your_program *
.quelle
perl
oder verwendenpython
.