Kopieren Sie die ersten n Dateien von einem Verzeichnis in ein anderes

Ich möchte die ersten 'n' Dateien von einem Verzeichnis in ein anderes Verzeichnis kopieren, vorzugsweise nur mit CLI-Tools (keine Skripte).

Ich habe folgendes versucht:

  • find . -maxdepth 1 -type f | head -5 | xargs cp -t /target/directory

    Dies sah vielversprechend aus, schlug jedoch fehl, da der Befehl osx den Schalter cpnicht zu haben scheint
    -t

  • execin ein paar verschiedenen Konfigurationen

    Dies ist wahrscheinlich wegen Syntaxproblemen auf meiner Seite fehlgeschlagen: /
    Ich konnte anscheinend keine headTypauswahl zum Laufen bringen

Jede mögliche Hilfe oder Vorschläge würden geschätzt.

Vielen Dank im Voraus!

Antworten (2)

Sie benötigen die -JOption mit xargs.

find . -maxdepth 1 -type f | head -n5 | xargs -J X cp X /target/directory

Die JOption fügt alle Dateinamen in den Platzhalter X ein, der beliebige Zeichen sein kann, und cpakzeptiert mehrere Dateien in einem Zielverzeichnis. Es kann visualisiert werden als-

cp file1 file2 file3 file4 file5 DESTINATION

BEARBEITEN:

Um Dateinamen mit Leerzeichen zu handhaben, haben wir trdas Zeilenumbruchzeichen nach jedem Dateinamen in das Nullzeichen übersetzt und dann xargs das Nullbit als Trennzeichen für die Dateinamen behandeln lassen.

 find . -maxdepth 1 -type f | head -n5 | tr '\n' '\0' | xargs -0 -J X cp -- X /target/directory
Ausgezeichnete Lösung, genau das, wonach ich gesucht habe! Können Sie das 'n' in erklären head -n5? Auf jeden Fall vielen Dank und danke auch @user3439894 für deinen Beitrag!
@visyoual - Aus dem Handbuch: ` head [-n count | -c Bytes] [Datei ...]`
OK. Bei meiner Suche nach anderen Lösungen vor dem Posten dieser Fragen hatten mehrere den Kopfbefehl mit -5und nicht -n5. Ich war mir nicht sicher, ob das eine akzeptable Kurzschrift oder ein Syntaxfehler war. Ich glaube, ich bin mir immer noch nicht sicher.
Wie Sie mir in einem Kommentar zu meiner Antwort erwähnt haben, verarbeitet Ihre Lösung keine Dateinamen mit Leerzeichen. Gibt es eine Möglichkeit, dies zu erreichen, indem Sie Ihren Befehl leicht ändern?
@visyoual, JSYK Wenn Ihre Dateinamen Leerzeichen enthalten, funktioniert die Lösung von fd0 nicht mit Dateinamen, die Leerzeichen enthalten, und Sie können die Lösung in meiner Antwort verwenden, die fd0 verbessert hat, bis er seine Antwort aktualisiert.
@visyoual - hängt von der Version von head ab, die Sie verwenden. Mit GNU head -n5würde die ersten fünf Zeilen bedeuten und -5alle bis auf die letzten fünf Zeilen. Bei BSD Head sind beide gleich.
@fd0 Danke für die Klarstellung. Auf die Gefahr hin, hier mein Glück zu drücken = ] Wäre eine Lösung, die Leerzeichen in Dateinamen behandelt, deutlich anders, oder wäre die Verwendung der Antwort von @ user3439894 die nächstbeste Lösung? (rein akademisch)
@visyoual, fd0 hat seine Antwort aktualisiert, ich würde seine aktualisierte Antwort über meine verwenden.
@fd0, warum verwendest du nicht einfach den aktualisierten Befehl und entfernst den, der keine Leerzeichen verarbeitet? Ist es dann ein Grund, beide Versionen aus Sicht der angewandten Nutzung zu haben?

Ich habe eine andere Lösung ohne xargsoder gefunden -exec, aber ich denke, die Antwort von fd0 ist ein besserer Weg:

while IFS= read -r f; do cp "$f" "/target/directory/"; done < <(find . -maxdepth 1 -type f | head -n5)
Ich schlage vor, dass Sie IFSauf nichts setzen IFS=, um führende oder nachgestellte Leerzeichen in einem Dateinamen zu behandeln und die Prozessersetzung anstelle der Befehlsersetzung und einer Here-Zeichenfolge zu verwenden. Ihre Lösung wird definitiv langsamer sein, aber sie wird Dateinamen mit Leerzeichen verarbeiten. Meine Lösung wird nicht in ihrer jetzigen Form.
@fd0, Guter Vorschlag. Ich weiß damit, IFS=wäre aber nicht sicher, wie man die Befehlsersetzung und hier die Zeichenfolge für die ProzessersetzungIFS=; while read ... austauscht , ohne etwas zu recherchieren. Es würde mir nichts ausmachen, wenn Sie mir meine Antwort zeigen oder sogar bearbeiten, danke.
Danke @fd0, ich habe das Extra <in ... done < <( ...meinen Tests verpasst. :)