Kopieren von Dateien in einer Pipeline mit cygwin bash shellscript

312
Stumac

Ich muss bestimmte Dateien in einem Verzeichnis auswählen und sie mithilfe eines cygwin-Skripts in ein anderes Verzeichnis kopieren, aber ich kann die Syntax für die Kopie nicht erhalten. dh

für i in cat boards do ls -t $ work | grep ^ $ i | cp .............

Wenn ich nur mit grep laufe, listet es alle Dateien auf, die ich will, aber ich weiß nicht, wie ich das auf dem cp-Befehl erhalten kann.

Ich habe schon lange nichts davon getan, aber ich erinnere mich, dass es eine automatische Variable gibt, die die Eingabe von stdin enthält. Jede Hilfe geschätzt.

2

2 Antworten auf die Frage

1
Peter Berbec

Sounds like you're hunting for xargs.

destination="/path/to/folder" for i in $(cat boards) do ls -t $work | grep ^$i | xargs -Isource cp source /path/to/destination done 

Run a for loop using variable i filled with the results of cat boards ($() spawns a process).

xargs -Isource takes the output of grep ^$i and feeds it to cp in the source position of cp source /path/to/destination. From the man page:

-I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input.

Hope this was what you were looking for.

1
minnmass

Ich gehe davon aus, dass Sie möchten, dass alle kopierten Dateien am selben Ort gespeichert werden.

Es klingt, Sie möchten, dass alle Dateien in / path / bis / $ funktionieren, bei denen der Dateiname mit einer Zeile aus der Board-Datei beginnt, die in ein Ziel kopiert werden soll.

zB gegeben

$ cat boards start1 start2 $ ls $work start1.txt start1.jpg start2.txt start2.jpg start3.txt $ 

Sie möchten, dass start1.txt, start1.jpg, start2.txt und start2.jpg nach irgendwo kopiert werden, aber nicht in start3.txt.

Verwenden Sie kein xargs: Es ist ein fantastisches Werkzeug, aber es wird Probleme verursachen, wenn Ihre Dateien oder "Suchmuster" Leerzeichen oder Glob-Zeichen (z. B. "*") enthalten.

Vielmehr nutzt ein Tool, das ein Suchmuster erwartet, findet .

cat boards | while read pattern find $work -name "$*" -exec cp {} /path/to/destination + done 

Das wird in jeder Zeile boardsals Suchmuster gelesen . findsucht dann im $workVerzeichnis nach passenden Dateien (und Ordnern!) $*; Jedes gefundene Element (Datei oder Ordner) wird an cp als ordnungsgemäß maskierter Parameter übergeben (an {}Ort und Stelle), und es wird eine xargsMinimierung der Anzahl von cpProzessen vorgenommen, die aufgrund dessen gestartet werden +(wenn Sie genau einen Prozess pro gefundenes Objekt, würden Sie ;stattdessen ein verwenden.

findEs gibt eine Vielzahl von Filtern, mit denen Sie Ihre Suche eingrenzen können. Besonders hervorzuheben ist die -type fOption, mit der die Ergebnisse auf die Datei beschränkt werden.

Beachten Sie, dass der cpBefehl möglicherweise fehlschlägt, wenn Ordner in der Argumentliste enthalten sind find. Die Verwendung des -type fFilters verhindert dies.

Beachten Sie auch, dass der cpBefehl das Ausgabeverzeichnis "glättet". Wenn $workUnterverzeichnisse vorhanden sind, die übereinstimmende Dateien enthalten, werden diese Dateien direkt in kopiert /path/to/destination. Wenn Sie zum Kopieren von Dateien auf der obersten Ebene von nur wollen $work, die -maxdepthFilter (wahrscheinlich mit einem Wert von 1: -maxdepth 1) zu verhindern, wird findvon Rekursion zu tief unten im Dateisystem.

Beachten Sie auch, dass finddie Groß- und Kleinschreibung beachtet wird. Wenn Sie dies nicht möchten, können Sie die Suche -inameanstelle von -nameGroß- und Kleinschreibung verwenden.

Wenn Sie andere Befehlszeilenparameter angeben möchten cp, setzen Sie diese einfach vor die {}(z. B. cp -r {}um Verzeichnisse zu kopieren, die dem Suchmuster entsprechen).

Guter Punkt zu seltsamen Dateinamen. Es gibt eine Lösung in beide Richtungen, aber IFS = und -print0 werden hässlich. Eine mögliche Anpassung an Ihre Suchlösung, verwenden Sie möglicherweise -exec cp "{}" `, um die unvermeidlichen Leerzeichen einzufangen? Peter Berbec vor 6 Jahren 0
Die {} erledigt das schon; Wenn Sie sie zitieren, wird nur ein paar geschweifte geschweifte Klammern an cp gesendet, das sich über keine solche Datei beschwert. minnmass vor 6 Jahren 1
Nur getestet, und wir haben beide recht! :) Die bloße Klammer funktioniert auch mit Dateinamen, einschließlich Leerzeichen, in doppelten Anführungszeichen (`" {} "`). Die Art und Weise, von der ich dachte, dass sie nicht funktionieren würde, die Verwendung von einfachen Klammern (`'{}'`) funktionierte ebenfalls gut. Ich nahm an, dass die einfachen Anführungszeichen die Klammern als Argumente übergeben hätten, aber ich denke nicht. Das Entkommen der geschweiften Klammern ist erfolgreich. Das Scannen von Anführungszeichen schlägt fehl. Wenn Sie die geschweiften Klammern in einer beliebigen Art von Anführungszeichen übergehen, schlägt die Option `` stat '\ {\}' `fehl. Das Verschieben von Anführungszeichen mit gescheiterten Klammern schlägt mit einem `kann stat` mit dem Dateinamen fehl, als ob er mit einem Anführungszeichen begonnen hätte. Peter Berbec vor 6 Jahren 1
Tief; Die Curlys sind Argumente, die man finden kann, also würde es natürlich funktionieren, sie zu zitieren. Entschuldigung, ich war dort stumm. minnmass vor 6 Jahren 0
Nein, mein Dummkopf. Ich wusste nicht, dass die Curlys richtig entkommen sind. Peter Berbec vor 6 Jahren 0