Folgendes sollte auf absolut allen Pfaden funktionieren.
Deklarieren Sie eine Funktion, um head
verwenden zu können und tail
bei NUL-separierter Ausgabe:
nul_terminated() {
tr '\0\n' '\n\0' | "[email protected]" | tr '\0\n' '\n\0'
}
Dann können Sie es verwenden, um eine NUL-getrennte Liste von Pfaden aus Ihrer Suche zu erhalten, nachdem Sie tail
durchlaufen haben :
find . -exec printf '%s\0' {} \; | nul_terminated tail -n 2
Sie können das dann an xargs
weiterleiten und fügen Sie Ihre Optionen hinzu:
find . -iname "*FooBar*" -exec printf '%s\0' {} \; | nul_terminated tail -n 2 | xargs -I "{}" -0 cp "{}" "dest"
Erklärung:
find
Dateien im aktuellen Verzeichnis (.
) und unten mit einem Namen, derfoobar
enthält (Groß-/Kleinschreibung wird wegeni
nicht beachtet in-iname
);- Führen Sie für jede Datei (
-exec
) ein Befehl zu - jeden Dateipfad drucken (
{}
) gefolgt von einem NUL-Zeichen (\0
) einzeln (\;
); - Zeilenumbrüche und NUL-Zeichen austauschen (
tr '\0\n' '\n\0'
);" - holen Sie sich die letzten beiden Zeilen (d. h. Pfade;
tail -n 2
,"[email protected]"
); - Vertauschen Sie erneut Zeilenumbrüche und NUL-Zeichen, um eine NUL-separierte Liste von Dateinamen zu erhalten (
tr '\0\n' '\n\0'
).
Die xargs
Befehl ist etwas schwieriger zu erklären. Es baut so viele cp ... "dest"
Befehle nach Bedarf, um in die maximale Befehlslänge zu passen des Betriebssystems und ersetzt den {}
Token im Befehl mit dem tatsächlichen Dateinamen (-I "{}" ... "{}"
), wobei beim Lesen der Parameter das NUL-Zeichen als Trennzeichen verwendet wird (-0
).
Sie können es versuchen
cp $(find . -iname "*FooBar*" | tail -2 ) dest
find . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
Leider funktioniert dies nicht mit Dateinamen, die Leerzeichen oder Zeilenumbrüche enthalten.