Einzeiler, um bestimmte Files zusammenzukopieren

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
dirk11
Beiträge: 2840
Registriert: 02.07.2013 11:47:01

Einzeiler, um bestimmte Files zusammenzukopieren

Beitrag von dirk11 » 08.06.2015 19:09:13

Hi Leute,

gesetzt den Fall, ich befinde mich im Unterverzeichnis home/user/temp.
Dieses hat wieder 100e Unterverzeichnisse. In einigen davon befinden sich *.ttf Dateien. Die hätte ich jetzt gerne alle dorthin kopiert, wo ich mich gerade befinde. Wie kriege ich das mit einem Einzeiler hin?

Kommt irgendwo drin "find . -name *.ttf" vor, denke ich. Und sonst?

DeletedUserReAsG

Re: Einzeiler, um bestimmte Files zusammenzukopieren

Beitrag von DeletedUserReAsG » 08.06.2015 19:12:41

Und sonst?
exec, cp und {} müssen auch noch rein, denke ich.

dirk11
Beiträge: 2840
Registriert: 02.07.2013 11:47:01

Re: Einzeiler, um bestimmte Files zusammenzukopieren

Beitrag von dirk11 » 08.06.2015 19:15:38

Dankeee, daraus konnte ich was frickeln ;)

Code: Alles auswählen

find . -name *.ttf -exec cp {} . \;

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Einzeiler, um bestimmte Files zusammenzukopieren

Beitrag von Cae » 08.06.2015 22:31:00

Das * sollte escapt werden, sonst expandiert es auf moeglicherweise schon vorhandene Dateien.

Schoener:

Code: Alles auswählen

$ find /path/to/source/ -name '*.ttf' -print0 | xargs -0r -- cp -t .
Erklaerung:

find | xargs ist effizienter, weil nicht fuer jeden Kopiervorgang ein neuer (cp-)Prozess gestartet werden muss, sondern die komplette verfuegbare Kommandozeile (meist 8k Zeichen) ausgenutzt wird, d.h. ein cp kann nun mehrere Hundert Dateien auf einmal kopieren. Entsprechend entfallen mehrere Hundert ueberfluessige fork()s.

Allerdings sind die Pfadtrenner bei find bzw. dem automatisch verwendeten find -print ganz normale Newlines, die auch in einem Dateinamen vorkommen koennten. -print0 und xargs -0 verwendet dagegen Nullbytes, die es im Dateisystem nicht geben kann. Das Flag -t bei cp gibt das Zielverzeichnis an, sodass man

Code: Alles auswählen

$ cp -t target a b c d
schreiben kann anstatt

Code: Alles auswählen

$ cp a b c d target
xargs kann die Argumente (hier: Dateipfade, die find liefert) nur hinten an die Kommandozeile anfuegen.

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

wanne
Moderator
Beiträge: 7548
Registriert: 24.05.2010 12:39:42

Re: Einzeiler, um bestimmte Files zusammenzukopieren

Beitrag von wanne » 08.06.2015 23:59:56

Ein equivalent zu dem:

Code: Alles auswählen

find /path/to/source/ -name '*.ttf' -print0 | xargs -0r -- cp -t .
Schöner und schneller...

Code: Alles auswählen

find /path/to/source/ -name '*.ttf' -exec cp -t . {} +
Dafür hat man halt das 8k limit. Nimmt man an, dass ein Pfad im schmitt 15 Zeichen hat (Was eher extrem kurz ist Beispiel ./musik/favorit/meine_lieblingsdate.mp3 hat 40 Zeichen 15 wären ./ord/mini.mp3), ist das maximal bei mir nichtmal eine Sekunde, die eingespart werden kann.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
Meillo
Moderator
Beiträge: 9235
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Einzeiler, um bestimmte Files zusammenzukopieren

Beitrag von Meillo » 09.06.2015 10:40:59

Wenn es um nur eine Verzeichnisstufe tiefer geht (das ist mir nicht klar geworden), dann doch ganz einfach so:

Code: Alles auswählen

cp */*.ttf .
Und in einer neueren bash oder der zsh fuer beliebig tiefe Unterverzeichnisse AFAIK auch so:

Code: Alles auswählen

cp **/*.ttf .
Portabel geht's auf dem von euch bereits beschrittenen Weg.
Use ed once in a while!

Antworten