Hi Folks, als verwöhnter "Mausschubser" ;-) habe ich mal 'ne blöde bash-Frage: Wie kann ich auf der Konsole viele (> 10.000) Dateien kopieren? cp bringt 'ne Fehlermeldung wegen zu langer Argumentliste. Any hints? Danke Timothy -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
On Wednesday 05 September 2007 10:00:26 Timothy Kesten wrote:
Hi Folks,
als verwöhnter "Mausschubser" ;-) habe ich mal 'ne blöde bash-Frage: Wie kann ich auf der Konsole viele (> 10.000) Dateien kopieren? cp bringt 'ne Fehlermeldung wegen zu langer Argumentliste.
Any hints?
Mit cp *.* /zum/zielverzeichnis Geht fast genauso wie der copy-Befehl unter DOS. Bye Michael -- Alles, was sich zu lange hinschleppt, ehe es zu etwas nur irgend Sichtbarem wird, verliert an Interesse. -- Wilhelm von Humboldt _____________________________________________________________________________ http://macbyte.info/ Mobile Loadavg.: 0.06 0.48 0.77 http://dattuxi.de/ Registered Linux User #228306 Linux 2.6.20-16-x86_64 ICQ #151172379 -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Mittwoch, 5. September 2007 schrieb Michael Raab:
On Wednesday 05 September 2007 10:00:26 Timothy Kesten wrote:
Hi Folks,
als verwöhnter "Mausschubser" ;-) habe ich mal 'ne blöde bash-Frage: Wie kann ich auf der Konsole viele (> 10.000) Dateien kopieren? cp bringt 'ne Fehlermeldung wegen zu langer Argumentliste.
Any hints?
Mit cp *.* /zum/zielverzeichnis
Geht fast genauso wie der copy-Befehl unter DOS.
nein das geht gerade nicht, denn 1. *.* "liefert" nur Dateien, welche mindestens einen Punkt enthalten 2. *.* wird unter einer Bourne-Shell ausgewertet, mach einfach mal: set -x ls *.* und versuche das Ergebnis zu verstehen Das Ergebnis wird sein, daß das Komando "ls" mit allen Dateien aufgerufen wird, die auf das Muster *.* passen. Wenn die Länge der so gefunden Dateinamen zu groß ist (unter Linux ca. 20Kbyte) dann gibt's eben obige Fehlermeldungen. Lösung: xargs oder Schleifen. Die DOS-Shell hingegen arbeitet anders. Hier werden die drei Zeichen "*.*" an das copy-Programm übergeben, und copy "sucht" dann die Dateien, welche auf das Muster passen. Man kann dem Unix "cp" auch das Muster übergeben: cp "*.*" foo nur wird dann _eine_ Datei namens *.* kopiert, sondenn es eine solche gibt. D,h. die Shell expandiert das Muster *.* nicht, da es in " eingeschlossen ist. Bye Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 92 04 87 1 Fax: +49(721) 92 04 87 2 Juergen.Vollmer@informatik-vollmer.de www.informatik-vollmer.de Internet-Telefonie: www.skype.com Benutzer: juergen.vollmer
Es handelt sich um ca. 11.000 Mails (aus KMail), die ich a) in ein Archivverzeichnis kopieren möchte und anschließend b) in KMail löschen (ich denke mal, ein verschieben aus einem KMail-Verzeichnis ist nicht so gut, da eventuell KMail dann durcheinander kommt, oder?). Egal ein cp * /Zielverzeichnis bringt die Meldung: [tk@main cur]$ cp * /media/data/testtmp/ bash: /bin/cp: Die Argumentliste ist zu lang [tk@main cur]$ Also es geht sooo nicht mit cp. Daher ja meine Frage. Ich könnte ja den Konqueror nehmen. Aber der ist ja auch so lahm. Übrigens - ein find * auf diese Daten führt auch zu o.g. Fehlermeldung. Timothy -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Mittwoch, 5. September 2007 14:24 schrieb Timothy Kesten:
Es handelt sich um ca. 11.000 Mails (aus KMail), die ich
a) in ein Archivverzeichnis kopieren möchte
und anschließend
b) in KMail löschen (ich denke mal, ein verschieben aus einem KMail-Verzeichnis ist nicht so gut, da eventuell KMail dann durcheinander kommt, oder?). Egal
ein cp * /Zielverzeichnis bringt die Meldung:
[tk@main cur]$ cp * /media/data/testtmp/ bash: /bin/cp: Die Argumentliste ist zu lang [tk@main cur]$
Also es geht sooo nicht mit cp.
Daher ja meine Frage. Ich könnte ja den Konqueror nehmen. Aber der ist ja auch so lahm.
Übrigens - ein find * auf diese Daten führt auch zu o.g. Fehlermeldung.
find listet ja nur die Dateien, und das erste Argument von find muß ein Verzeichnis sein: find Verzeichnis -type f -print Listet alle "echten" Dateien in Verzeichnis und allen Unterverzeichnissen auf. Achtung Mails in KMAIL werden in Verzeichnissen gespeichert (falls man maildir benutzt). Ich würde das Kopieren von sovielen Dateien rsync benutzen. Das kopiert die Ordnerstrukturen gleich mit: mkdir zielverzeichnis rsync -av quellverzeichnis/ zielverzeichnis/ Achtung: die abschliessenden / nicht vergessen! Bye Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 92 04 87 1 Fax: +49(721) 92 04 87 2 Juergen.Vollmer@informatik-vollmer.de www.informatik-vollmer.de Internet-Telefonie: www.skype.com Benutzer: juergen.vollmer
Am Mittwoch, 5. September 2007 14:35 schrieb Dr. Jürgen Vollmer:
Ich würde das Kopieren von sovielen Dateien rsync benutzen. Das kopiert die Ordnerstrukturen gleich mit:
mkdir zielverzeichnis rsync -av quellverzeichnis/ zielverzeichnis/
Achtung: die abschliessenden / nicht vergessen!
Danke, dass funzt Timothy -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Hallo Timothy, also wenn die Systemlast egal ist, kommst du mit: find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \; recht weit. Dabei ist zu beachten das "\;" ganz am ende angegeben werden muss um dem exec zu sagen wann der Befehl fertig ist. Das "{}" wird dabei von find automatisch mit dem gefundenen Dateinamen samt Pfad gefüllt. Ist aber wirklich nicht gerade resourcen schonend das ganze. Timothy Kesten schrieb:
Hi Folks,
als verwöhnter "Mausschubser" ;-) habe ich mal 'ne blöde bash-Frage: Wie kann ich auf der Konsole viele (> 10.000) Dateien kopieren? cp bringt 'ne Fehlermeldung wegen zu langer Argumentliste.
Any hints?
Danke Timothy
- -- Gruß Horst - -- "Wer A sagt muss nicht B sagen, er kann auch erkennen das A falsch war!" (Berthold Brecht) -----BEGIN PGP SIGNATURE----- Version: PGP Desktop 9.6.2 (Build 2014) Charset: UTF-8 wsBVAwUBRt5lArbCXWAFTgLjAQgvuQf+P+g3YiAQXxw+br0WaXoZHqDCjJ1mXv1l RpsuKFhE6Bs6PJsxbU+Q3IWh1whPMBDj88NDV8DOQOt2/2sWzjogiNnGTrTV6+J/ 3747sjjEJ2Vo+frWHRxnNHypGijvU7N1y3aS4JVooxV2MVROT8qefUhrSlK0XsLJ peXUn3a29xtoARyc3LtOFKDOndQQtFwnI5NhsGF8NC3H8BZJ5VAL9q+fi5oOeJM2 52W/11QwdwHlvUAh/pnL5gBsykIfT1dDpJjWcdFHpt+VC+QXuLB+GO0tDL8NDiwg +BBa70H4iBlgUKoImT6oumclQ9IEeiLUDPof8mbsEvjIoe4Vw/wEag== =GJdA -----END PGP SIGNATURE----- -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am 05.09.07 schrieb Horst Templer
also wenn die Systemlast egal ist, kommst du mit:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \;
man xargs Gruß Martin -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Mittwoch, 5. September 2007 17:58 schrieb Martin Schröder:
Am 05.09.07 schrieb Horst Templer
: also wenn die Systemlast egal ist, kommst du mit:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \;
man xargs
und wie gibt man hier das Zielverzeichnis als _letztes_ Argument von cp an? Bye Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 92 04 87 1 Fax: +49(721) 92 04 87 2 Juergen.Vollmer@informatik-vollmer.de www.informatik-vollmer.de Internet-Telefonie: www.skype.com Benutzer: juergen.vollmer
On Wednesday 05 September 2007 18:14, Dr. Jürgen Vollmer wrote:
Am Mittwoch, 5. September 2007 17:58 schrieb Martin Schröder:
Am 05.09.07 schrieb Horst Templer
: also wenn die Systemlast egal ist, kommst du mit:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \;
man xargs
und wie gibt man hier das Zielverzeichnis als _letztes_ Argument von cp an?
find ... -print0 | xargs -0i^ cp ^ /path/to/destination/directory Torsten
Torsten Foertsch am Mittwoch, 5. September 2007 19:46:
On Wednesday 05 September 2007 18:14, Dr. Jürgen Vollmer wrote:
und wie gibt man hier das Zielverzeichnis als _letztes_ Argument von cp an?
find ... -print0 | xargs -0i^ cp ^ /path/to/destination/directory
ich verstehe die Man-Page von xargs und -i (oder neuer -I) -I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1. -L max-lines Use at most max-lines nonblank input lines per command line. Trailing blanks cause an input line to be logically continued on the next input line. Implies -x. --exit, -x Exit if the size (see the -s option) is exceeded. so, daß dann immer nur eine Datei pro Aufruf con cp kopiert wird. Dann hat man aber nichts gegenüber -exec gewonnen. Bye Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 92 04 87 1 Fax: +49(721) 92 04 87 2 Juergen.Vollmer@informatik-vollmer.de www.informatik-vollmer.de Internet-Telefonie: www.skype.com Benutzer: juergen.vollmer ------------------------------------------------------------------------------- Diese EMail ist elektronisch mittels GPG / PGP signiert. Diese elektronische Unterschrift ist in einem EMail-Anhang enthalten. Leider kann die Signatur ohne die Installation entsprechender Programme weder geprüft noch angezeigt werden. Mehr dazu unter: http://www.gnupg.org oder auch http://www.pgpi.org -------------------------------------------------------------------------------
Hallo, Am Donnerstag, 6. September 2007 09:41 schrieb Dr. Jürgen Vollmer:
Torsten Foertsch am Mittwoch, 5. September 2007 19:46:
On Wednesday 05 September 2007 18:14, Dr. Jürgen Vollmer wrote:
und wie gibt man hier das Zielverzeichnis als _letztes_ Argument von cp an?
find ... -print0 | xargs -0i^ cp ^ /path/to/destination/directory
ich verstehe die Man-Page von xargs und -i (oder neuer -I)
-I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1. -L max-lines Use at most max-lines nonblank input lines per command line. Trailing blanks cause an input line to be logically continued on the next input line. Implies -x.
--exit, -x Exit if the size (see the -s option) is exceeded.
so, daß dann immer nur eine Datei pro Aufruf con cp kopiert wird.
Das interpretiere ich auch so, weil es sozusagen die Universalform von cp ist. Gestützt wird dies durch "xargs reads arguments from the standard input, [...], and executes the command (default is /bin/echo) one or more times with any initial-arguments followed by arguments read from standard input." Besser hieße es hier vielleicht am Schluß: "... followed by an argument read from standard input.", aber es heißt ja auch "... one or more times ...". Wozu wären mehrere Aufrufe nötig, wenn xargs alle von stdin gelesenen Argumente gleich gesammelt an das Kommando (hier cp) übergeben würde? Außerdem ginge das nur, wenn die Argumente echte Dateinamen (gesichert durch find -type f) wären und das Ziel ein Verzeichnis wäre. Woher soll xargs das wissen bzw. die Spezialsyntax "cp SOURCE-FILES DIRECTORY" kennen?
Dann hat man aber nichts gegenüber -exec gewonnen.
So ist es. Eine kleine Betrachtung, warum find recht nützlich sein kann (obwohl es im urspr. Beitrag nur um das Kopieren von 11.000 Mail-Dateien, anscheinend aber nicht von Verzeichnissen, ging): Ich lege Testverzeichnisse und -dateien an, so daß in einem Testverzeichnis cptest_SOURCEDIR die Verzeichnisse SOURCEDIR_1 bis _9 (hier ohne jeweils eigene Unterverzeichnisse) und die Dateien SOURCEFILE_1 bis _9 liegen. Das Testverzeichnis cptest_DESTDIR ist zunächst leer. Mit "cp -R SOURCEDIR_* DESTDIR" wird es erst möglich auch Verzeichnisse nach DESTDIR zu kopieren, allerdings werden dann _alle_ Verzeichnisse und diese auch noch _rekursiv_ kopiert und nicht nur bestimmte Verzeichnisse (und evtl. Dateien) in cptest_SOURCEDIR. Mit find kann man das durch die gezielte Einschränkung der Argumentliste beeinflussen: $> cd cptest_SOURCEDIR $> find ./ -path "./SOURCEDIR_[6-9]" -prune -or -print bedeutet, daß alle Verzeichnisse von SOURCEDIR_6 bis SOURCEDIR_9, sowie - im Ggs. zu "cp -R"! - deren Dateien _und_ Unterverzeichnisse übersprungen werden. Nur die Verzeichnisse SOURCEDIR_1 bis SOURCEDIR_5 und die Dateien SOURCEFILE_1 bis SOURCEFILE_9 werden verarbeitet (hier nur untereinander ausgegeben). Kopieren: $> cd cptest_SOURCEDIR $> find ./ -path "./SOURCEDIR_[6-9]" -prune -or \ -exec cp -R "{}" ../cptest_DESTDIR ";" Natürlich hätte man auch schon bei cp mit diesem Shell-Pattern arbeiten können, aber die Rekursion in evtl. darunterliegende Verzeichnisse hätte noch stattgefunden. In -path kann man nur Shell-Patterns verwenden. Mit -regexp geht dann mehr: $> find ./ -regex "./SOURCE\(DIR\|FILE\)_[6-9]" -prune -or \ -exec cp -R "{}" ../cptest_DESTDIR ";" Wie ich so damit herumspiele, stelle ich fest, daß trotz des Ausschlusses der Verzeichnisse SOURCEDIR_6 bis _9 und der Dateien SOURCEFILE_6 bis _9 mittels "-or" (Ergebnis des Tests mit -regex = true) _alle_ Verzeichnisse und Dateien kopiert werden. Wenn man statt "-exec" die Aktion "-print" verwendet, werden, wie erwartet, nur die Verzeichnisse SOURCEDIR_1 bis _5 und die Dateien SOURCEFILE_1 bis _5 ausgegeben. Wenn ich "-exec" durch "-ok" ersetze, dann funktioniert es wie erwartet (diesmal mit einer Frage für jedes Objekt, ob es kopiert werden soll). Laut "man find" sollte bei einer Verknüpfung mit "-or" der rechte Teil nicht ausgeführt werden, wenn der linke Teilausdruck schon "true" ergibt: expr1 -o expr2 Or; expr2 is not evaluated if expr1 is true. Warum funktioniert das bei "-exec" nicht? Habe ich einen Bug entdeckt? Gruß, Tom -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hi Thomas! On Thu, 06 Sep 2007, Thomas Michalka wrote:
$> cd cptest_SOURCEDIR $> find ./ -path "./SOURCEDIR_[6-9]" -prune -or \ -exec cp -R "{}" ../cptest_DESTDIR ";"
Das hätte aber auch nicht funktionieren sollen.
$> find ./ -regex "./SOURCE\(DIR\|FILE\)_[6-9]" -prune -or \ -exec cp -R "{}" ../cptest_DESTDIR ";"
Wie ich so damit herumspiele, stelle ich fest, daß trotz des Ausschlusses der Verzeichnisse SOURCEDIR_6 bis _9 und der Dateien SOURCEFILE_6 bis _9 mittels "-or" (Ergebnis des Tests mit -regex = true) _alle_ Verzeichnisse und Dateien kopiert werden. Wenn man statt "-exec" die Aktion "-print" verwendet, werden, wie erwartet, nur die Verzeichnisse SOURCEDIR_1 bis _5 und die Dateien SOURCEFILE_1 bis _5 ausgegeben.
Das glaube ich nicht: ,---- | ~$ ls foobar | SRC_DIR1 SRC_DIR4 SRC_DIR7 SRC_FILES1 SRC_FILES4 SRC_FILES7 | SRC_DIR2 SRC_DIR5 SRC_DIR8 SRC_FILES2 SRC_FILES5 SRC_FILES8 | SRC_DIR3 SRC_DIR6 SRC_DIR9 SRC_FILES3 SRC_FILES6 SRC_FILES9 | | ~$ cd foobar | ~/foobar$ find . -regex "./SRC_\(DIR\|FILES\)[6-9]" -prune -or -print | . | ./SRC_FILES1 | ./SRC_FILES2 | ./SRC_FILES3 | ./SRC_FILES4 | ./SRC_FILES5 | ./SRC_DIR1 | ./SRC_DIR2 | ./SRC_DIR3 | ./SRC_DIR4 | ./SRC_DIR5 `---- Man beachte den ersten Fund von find, nämlich den ".". Und nun mach mal ein cp -R . ../DESTDIR und du wirst feststellen, dass alles wie "gewünscht" funktioniert hat. Auf die Schnelle konnte ich aber find nicht davon überzeugen, "." auszuschließen. Weder -path "." noch -regex "^.$" funktionierten.
Wenn ich "-exec" durch "-ok" ersetze, dann funktioniert es wie erwartet (diesmal mit einer Frage für jedes Objekt, ob es kopiert werden soll).
Warum das funktioniert, wundert mich dann aber doch. Mit freundlichen Grüßen, Christian -- hundred-and-one symptoms of being an internet addict: 243. You unsuccessfully try to download a pizza from www.dominos.com. -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hi Christian, Am Donnerstag, 6. September 2007 20:21 schrieb Christian Brabandt:
Hi Thomas!
On Thu, 06 Sep 2007, Thomas Michalka wrote:
$> cd cptest_SOURCEDIR $> find ./ -path "./SOURCEDIR_[6-9]" -prune -or \ -exec cp -R "{}" ../cptest_DESTDIR ";"
Das hätte aber auch nicht funktionieren sollen.
Tat es auch nicht. Hab's nur nicht erwähnt, weil ich mich gleich auf -regex gestürzt habe.
$> find ./ -regex "./SOURCE\(DIR\|FILE\)_[6-9]" -prune -or \ -exec cp -R "{}" ../cptest_DESTDIR ";"
Wie ich so damit herumspiele, stelle ich fest, daß trotz des Ausschlusses der Verzeichnisse SOURCEDIR_6 bis _9 und der Dateien SOURCEFILE_6 bis _9 mittels "-or" (Ergebnis des Tests mit -regex = true) _alle_ Verzeichnisse und Dateien kopiert werden. Wenn man statt "-exec" die Aktion "-print" verwendet, werden, wie erwartet, nur die Verzeichnisse SOURCEDIR_1 bis _5 und die Dateien SOURCEFILE_1 bis _5 ausgegeben.
Das glaube ich nicht:
,----
| ~$ ls foobar | SRC_DIR1 SRC_DIR4 SRC_DIR7 SRC_FILES1 SRC_FILES4 SRC_FILES7 | SRC_DIR2 SRC_DIR5 SRC_DIR8 SRC_FILES2 SRC_FILES5 SRC_FILES8 | SRC_DIR3 SRC_DIR6 SRC_DIR9 SRC_FILES3 SRC_FILES6 SRC_FILES9 | | ~$ cd foobar | ~/foobar$ find . -regex "./SRC_\(DIR\|FILES\)[6-9]" -prune -or -print | . | ./SRC_FILES1 | ./SRC_FILES2 | ./SRC_FILES3 | ./SRC_FILES4 | ./SRC_FILES5 | ./SRC_DIR1 | ./SRC_DIR2 | ./SRC_DIR3 | ./SRC_DIR4 | ./SRC_DIR5
`---- Man beachte den ersten Fund von find, nämlich den ".". Und nun mach mal ein cp -R . ../DESTDIR und du wirst feststellen, dass alles wie "gewünscht" funktioniert hat.
Danke für den Hinweis! Daß auch der Pfad ./ gefunden und durch den regulären Ausdruck nicht abgedeckt wird, ist die Ursache für das rekursive Kopieren _aller_ Verzeichnisse und Dateien schon beim ersten cp-Aufruf. Die weiteren Kopieraktionen laufen dann sozusagen vergeblich ab. Habe gerade noch was ausprobiert, -print durch -exec echo "{}" ";" ersetzt: $> find ./ -regex "./SOURCE\(DIR\|FILE\)_[6-9]" -or -exec echo "{}" ";" ./ ./SOURCEDIR_1 ./SOURCEDIR_2 ./SOURCEDIR_3 ./SOURCEDIR_4 ./SOURCEDIR_5 ./SOURCEFILE_1 ./SOURCEFILE_2 ./SOURCEFILE_3 ./SOURCEFILE_4 ./SOURCEFILE_5 Also kein "Logik-Bug" im Zshg. mit -exec.
Auf die Schnelle konnte ich aber find nicht davon überzeugen, "." auszuschließen. Weder -path "." noch -regex "^.$" funktionierten.
Sollte aber funktionieren, bei mir tut's das. Es genügt auch -regex "./*", welcher sowohl auf "." als auch auf "./" paßt: $> find ./ -regex "^.*SOURCE\(DIR\|FILE\)_[6-9]" -or \ -regex "./*" -or \ -exec echo "{}" ";" ./SOURCEDIR_1 ./SOURCEDIR_2 ./SOURCEDIR_3 ./SOURCEDIR_4 ./SOURCEDIR_5 ./SOURCEFILE_1 ./SOURCEFILE_2 ./SOURCEFILE_3 ./SOURCEFILE_4 ./SOURCEFILE_5 Mit -regex "^./$" funktioniert's natürlich auch. Man beachte die Ausgabe des Startpfades, der hinten einen Slash hat. Ich sehe gerade, daß dies von der Schreibweise des Startpfads hinter find abhängt. In den Fällen "keine Angabe" oder "." (wie bei Dir) hat man auch nur die erste Ausgabezeile mit ".". Nur find ./ liefert "./" Mein Konstrukt ist sicher noch etwas umständlich, denn es müßte doch möglich sein, einen regulären Ausdruck zu formulieren, der "./" auch erfaßt. Ah ja, so geht's also: $> pwd <pfad>/cptest_SOURCEDIR $> find ./ -regex "./*\|./SOURCE\(DIR\|FILE\)_[6-9]" -or -print ./SOURCEDIR_1 ./SOURCEDIR_2 ./SOURCEDIR_3 ./SOURCEDIR_4 ./SOURCEDIR_5 ./SOURCEFILE_1 ./SOURCEFILE_2 ./SOURCEFILE_3 ./SOURCEFILE_4 ./SOURCEFILE_5 Der eine Gesamtausdruck ist vielleicht eher was für regexp-Junkies ;-) Ich finde ihn etwas unübersichtlicher, als die zwei getrennten Ausdrücke mit der OR-Verknüpfung in find.
Wenn ich "-exec" durch "-ok" ersetze, dann funktioniert es wie erwartet (diesmal mit einer Frage für jedes Objekt, ob es kopiert werden soll).
Warum das funktioniert, wundert mich dann aber doch.
Sorry, das funktioniert freilich nicht, wie gewünscht, wenn man auf jede Frage mit "y" antwortet. Offenbar habe ich gestern auf die Schnelle bei der ersten Frage, ohne es zu merken, eine andere Taste erwischt. Vielen Dank an alle für die anregende Diskussion, die aus einer gar nicht dummen bash-Frage entstand, und die mich auch wieder mal mit Regular Expressions hat beschäftigen lassen. Gruß, Tom -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Don, 06 Sep 2007, Christian Brabandt schrieb: [..]
| ~/foobar$ find . -regex "./SRC_\(DIR\|FILES\)[6-9]" -prune -or -print | . | ./SRC_FILES1 [..] Man beachte den ersten Fund von find, nämlich den ".".
find . -mindepth 1 ... -dnh -- It's hard to be religious when certain people are never incinerated by bolts of lightning. -- Calvin -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Sonntag, 9. September 2007 20:27 schrieb David Haller:
Hallo,
Am Don, 06 Sep 2007, Christian Brabandt schrieb: [..]
| ~/foobar$ find . -regex "./SRC_\(DIR\|FILES\)[6-9]" -prune -or -print | . | ./SRC_FILES1
[..]
Man beachte den ersten Fund von find, nämlich den ".".
find . -mindepth 1 ...
Oh ja, so ist es natürlich viel eleganter bzw. so, wie es von den Programmautoren gedacht ist! Der Ausschluß der obersten Verzeichnisebene funktioniert so nämlich unabhängig davon, ob der Startsuchpfad identisch mit dem aktuellen Arbeitsverzeichnis ist. Obwohl ich die manpage einige Male auf dem Schirm hatte, bin ich nicht drübergestolpert. Vielen Dank für den Hinweis! Tom -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo Horst, Am Mittwoch, 5. September 2007 10:12 schrieb Horst Templer:
Hallo Timothy,
also wenn die Systemlast egal ist, kommst du mit:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \;
Auch die geschweiften Klammern müssen "escaped" (mit \) oder gequoted werden, damit sie die Shell nicht auswertet: $> find <verzeichnis> -type f -name "<Muster>" -exec cp "{""}" <Ziel> \; Evtl. braucht's für cp noch ein paar Optionen, um z.B. das Datum und ggf. die Rechte der Dateien zu erhalten (s. "man cp").
recht weit.
Dabei ist zu beachten das "\;" ganz am ende angegeben werden muss um dem exec zu sagen wann der Befehl fertig ist. Das "{}" wird dabei von find automatisch mit dem gefundenen Dateinamen samt Pfad gefüllt.
Nicht gefüllt, sondern ersetzt. Bye, Tom -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hi Horst! On Wed, 05 Sep 2007, Horst Templer wrote:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \;
[...]
Ist aber wirklich nicht gerade resourcen schonend das ganze.
Hinreichend neue finds unterstüzen auch + anstelle von \; ,---- | -exec command {} + | This variant of the -exec option runs the specified command on | the selected files, but the command line is built by appending | each selected file name at the end; the total number of invoca- | tions of the command will be much less than the number of | matched files. The command line is built in much the same way | that xargs builds its command lines. Only one instance of ’{}’ | is allowed within the command. The command is executed in the | starting directory. `---- Mit freundlichen Grüßen Christian -- Letzte Worte eines Chemikers: "Oh, jetzt habe ich etwas verschüttet." -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Mittwoch, 5. September 2007 21:44 schrieb Christian Brabandt:
Hi Horst!
On Wed, 05 Sep 2007, Horst Templer wrote:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \;
[...]
Ist aber wirklich nicht gerade resourcen schonend das ganze.
Hinreichend neue finds unterstüzen auch + anstelle von \;
,----
| -exec command {} + | This variant of the -exec option runs the specified command on | the selected files, but the command line is built by appending | each selected file name at the end; the total number of invoca- | tions of the command will be much less than the number of | matched files. The command line is built in much the same way | that xargs builds its command lines. Only one instance of ’{}’ | is allowed within the command. The command is executed in the | starting directory.
`----
Wenn ich das richtig verstehe, dann hängt find jeden gefundenen Dateinamen (base) an das Ende des Kommandos. Damit wäre ein cp <Filelist> <Zielpfad> in -exec nicht möglich, weil <Zielpfad> als DIRECTORY das letzte Argument von cp sein muß. Nur so läßt sich eine Liste von Dateien gemeinsam in ein Verzeichnis kopieren (man cp). Das war aber gerade nicht beabsichtigt, sondern es sollte eine große Menge an SOURCE-Files in ein anderes Verzeichnis kopiert werden. Außerdem stellt sich mir die Frage, ob man dann nicht auch gerade wieder die Situation hergestellt hat, die zur Frage eingangs der Diskussion führte, nämlich zu viele Argumente (bzw. zu lange Argumentliste) für cp. Abgesehen von diesen Spitzfindigkeiten finde ich die schon genannte Lösung mit rsync wesentlich eleganter. Wenn man die SOURCE-Files doch noch nicht gleich löscht, dann kann man rsync nochmal anwenden, und es werden nur noch die neu hinzugekommenen Dateien übertragen. Das spart dann erst richtig Zeit. Wenn es nicht zu berücksichtigende Unterverzeichnisse gibt, geht Ausschluß der Übertragung der Dateien bei rsync mindestens genauso elegant, wie bei find. Bye, Tom -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hi Thomas! On Wed, 05 Sep 2007, Thomas Michalka wrote:
Am Mittwoch, 5. September 2007 21:44 schrieb Christian Brabandt:
On Wed, 05 Sep 2007, Horst Templer wrote:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \; Ist aber wirklich nicht gerade resourcen schonend das ganze.
Hinreichend neue finds unterstüzen auch + anstelle von \;
[...]
Wenn ich das richtig verstehe, dann hängt find jeden gefundenen Dateinamen (base) an das Ende des Kommandos. Damit wäre ein cp <Filelist> <Zielpfad> in -exec nicht möglich, weil <Zielpfad> als DIRECTORY das letzte Argument von cp sein muß. Nur so läßt sich eine Liste von Dateien gemeinsam in ein Verzeichnis kopieren (man cp).
Tatsächlich. Irgendwie dachte ich, dass beide Versionen synonym zu benutzen sind. Also bleibt doch wieder xargs.
Außerdem stellt sich mir die Frage, ob man dann nicht auch gerade wieder die Situation hergestellt hat, die zur Frage eingangs der Diskussion führte, nämlich zu viele Argumente (bzw. zu lange Argumentliste) für cp.
Nein, find sorgt dafür dass ARG_MAX nicht erreicht wird.
Abgesehen von diesen Spitzfindigkeiten finde ich die schon genannte Lösung mit rsync wesentlich eleganter. Wenn man die SOURCE-Files doch noch nicht gleich löscht, dann kann man rsync nochmal anwenden, und es werden nur noch die neu hinzugekommenen Dateien übertragen. Das spart dann erst richtig Zeit. Wenn es nicht zu berücksichtigende Unterverzeichnisse gibt, geht Ausschluß der
Übertragung der Dateien bei rsync mindestens genauso elegant, wie bei find.
Klar, ich würde find benutzen, weil das halt immer vorhanden ist. Rsync ist natürlich genauso geeignet. Mit freundlichen Grüßen, Christian -- hundred-and-one symptoms of being an internet addict: 241. You try to look for Net Search even when you're in File Manager. -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo Christian, Am Donnerstag, 6. September 2007 07:39 schrieb Christian Brabandt:
Hi Thomas!
On Wed, 05 Sep 2007, Thomas Michalka wrote:
Am Mittwoch, 5. September 2007 21:44 schrieb Christian Brabandt:
On Wed, 05 Sep 2007, Horst Templer wrote:
find <verzeichnis> -type f -name "<Muster>" -exec cp {} <Ziel> \; Ist aber wirklich nicht gerade resourcen schonend das ganze.
Hinreichend neue finds unterstüzen auch + anstelle von \;
[...]
Wenn ich das richtig verstehe, dann hängt find jeden gefundenen Dateinamen (base) an das Ende des Kommandos. Damit wäre ein cp <Filelist> <Zielpfad> in -exec nicht möglich, weil <Zielpfad> als DIRECTORY das letzte Argument von cp sein muß. Nur so läßt sich eine Liste von Dateien gemeinsam in ein Verzeichnis kopieren (man cp).
Tatsächlich. Irgendwie dachte ich, dass beide Versionen synonym zu benutzen sind. Also bleibt doch wieder xargs.
Nicht unbedingt, man kann find -exec doch immer noch auf die konventionelle Weise verwenden (ohne das '+' hinter {}). Siehe meine Antwort auf Dr. J. Vollmer von Heute, 17:51 Uhr. N.B.: Bei der konventionellen Form von -exec darf der Platzhalter "{}" sogar mehrfach auftreten, auch wenn es in diesem Fall auch ohne das geht.
Außerdem stellt sich mir die Frage, ob man dann nicht auch gerade wieder die Situation hergestellt hat, die zur Frage eingangs der Diskussion führte, nämlich zu viele Argumente (bzw. zu lange Argumentliste) für cp.
Nein, find sorgt dafür dass ARG_MAX nicht erreicht wird.
Meine Version ist wohl etwas veraltet, weshalb das im meiner Manpage noch nicht steht. Ist das eine Umgebungsvariable oder eine Konstante in einem Quelltext von cp oder find? Gruß, Tom -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hi Thomas! On Thu, 06 Sep 2007, Thomas Michalka wrote:
Am Donnerstag, 6. September 2007 07:39 schrieb Christian Brabandt:
On Wed, 05 Sep 2007, Thomas Michalka wrote:
Am Mittwoch, 5. September 2007 21:44 schrieb Christian Brabandt:
Hinreichend neue finds unterstüzen auch + anstelle von \;
[...]
Wenn ich das richtig verstehe, dann hängt find jeden gefundenen Dateinamen (base) an das Ende des Kommandos. Damit wäre ein cp <Filelist> <Zielpfad> in -exec nicht möglich, weil <Zielpfad> als DIRECTORY das letzte Argument von cp sein muß. Nur so läßt sich eine Liste von Dateien gemeinsam in ein Verzeichnis kopieren (man cp).
Tatsächlich. Irgendwie dachte ich, dass beide Versionen synonym zu benutzen sind. Also bleibt doch wieder xargs.
Nicht unbedingt, man kann find -exec doch immer noch auf die konventionelle Weise verwenden (ohne das '+' hinter {}). Siehe meine Antwort auf Dr. J. Vollmer von Heute, 17:51 Uhr.
Ja klar. Ich bezog mich darauf, nicht für jedes Argument einen extra Prozess zu forken. Aber wir bereits entdeckt, funktioniert das auch nicht mit xargs, wenn man mit -I arbeitet.
Außerdem stellt sich mir die Frage, ob man dann nicht auch gerade wieder die Situation hergestellt hat, die zur Frage eingangs der Diskussion führte, nämlich zu viele Argumente (bzw. zu lange Argumentliste) für cp.
Nein, find sorgt dafür dass ARG_MAX nicht erreicht wird.
Meine Version ist wohl etwas veraltet, weshalb das im meiner Manpage noch nicht steht.
Steht bei mir auch nicht direkt in der manpage, man kann es aber herauslesen: ,----[~$ man find |grep -A2 total ]- | -exec command {} + | [...] | each selected file name at the end; the total number of invoca- | tions of the command will be much less than the number of | matched files. The command line is built in much the same way | [...] | | ~$ find --version | GNU find Version 4.2.28 | Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION `---- Der Standard http://www.opengroup.org/onlinepubs/009695399/utilities/find.html erwähnt es auch
Ist das eine Umgebungsvariable oder eine Konstante in einem Quelltext von cp oder find?
Nein. Compileabhängige Variable des Kernels. Das wird in limits.h definiert. ,---- | ~$ getconf ARG_MAX | 131072 `---- Mit freundlichen Grüßen Christian -- hundred-and-one symptoms of being an internet addict: 242. You turn down a better-paying job because it doesn't come with a free e-mail account. -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Am Mittwoch, 5. September 2007 schrieb Timothy Kesten:
Hi Folks,
als verwöhnter "Mausschubser" ;-) habe ich mal 'ne blöde bash-Frage: Wie kann ich auf der Konsole viele (> 10.000) Dateien kopieren? cp bringt 'ne Fehlermeldung wegen zu langer Argumentliste.
Any hints? z.B. mit:
cd ziel-verzeichnis find quell-verzeichnis | tar -cvf- -T- | tar -xf- (ungestestet, mehr dazu in der Man-Page von tar) Bye Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 92 04 87 1 Fax: +49(721) 92 04 87 2 Juergen.Vollmer@informatik-vollmer.de www.informatik-vollmer.de Internet-Telefonie: www.skype.com Benutzer: juergen.vollmer
Hallo Timothy,
Hi Folks,
als verwöhnter "Mausschubser" ;-) habe ich mal 'ne blöde bash-Frage: Wie kann ich auf der Konsole viele (> 10.000) Dateien kopieren? cp bringt 'ne Fehlermeldung wegen zu langer Argumentliste. Das ist nicht ganz korrekt. Die Argumentliste ist zu lang für die in main() übergebbare Anzahl von Zeichen. Hilfreich wäre möglicherweise, wenn Du etwas näher spezifizieren würdest was wie kopiert werden soll; ich glaube eher, Du willst was verschieben (wozu etwas doppelt haben - braucht viel Platz).
Any hints?
cp ist ohnehin nicht das richtige Mittel zum Kopieren von großen Datenmengen. Besser sind hier die von Unix gelieferten Tools {tar|pax|rsync}. Dafür müsstest Du mal in die man(uals) sehen. Also man pax, oder ... Gerade weil es unter Unix schon immer notwendig war, sich neuen Bedingungen anzupassen, gibt es diese Tools. Die Tools sind sehr mächtig und man hat eine große Anzahl von Möglichkeiten zu bestimmen, was denn nun kopiert werden soll, dass man hier nicht alles aufschreiben kann und ein Blick in man(uals) wesentlich besser ist.
Danke Timothy
Gruß -- Uwe Lienig ---------- fon: (+49 351) 462 2780 fax: (+49 351) 462 3476 mailto:uwe.lienig@fif.mw.htw-dresden.de Forschungsinstitut Fahrzeugtechnik http://www.fif.mw.htw-dresden.de parcels: Gutzkowstr. 22, 01069 Dresden letters: PF 12 07 01, 01008 Dresden Hochschule für Technik und Wirtschaft Dresden (FH) Friedrich-List-Platz 1, 01069 Dresden -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Timothy Kesten schrieb:
Hi Folks,
als verwöhnter "Mausschubser" ;-) habe ich mal 'ne blöde bash-Frage: Wie kann ich auf der Konsole viele (> 10.000) Dateien kopieren? cp bringt 'ne Fehlermeldung wegen zu langer Argumentliste.
Any hints?
Danke Timothy
noch ein Vorschlag: rsync -av quelle ziel (ggfs. Parameter ändern wegen überschreiben/nicht überschreiben...) Fred -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
participants (11)
-
Christian Brabandt
-
David Haller
-
Dr. Jürgen Vollmer
-
Fred Ockert
-
Horst Templer
-
Martin Schröder
-
Michael Raab
-
Thomas Michalka
-
Timothy Kesten
-
Torsten Foertsch
-
Uwe Lienig