cp- eine Datei in mehrere Ordner kopieren

Seiler

Seiler

Aktives Mitglied
Thread Starter
Dabei seit
05.04.2005
Beiträge
244
Reaktionspunkte
2
Hallo,

hätte mal eine Frage. Ich hab eine Verzeichnisstruktur (1 Ordner in home und in diesem 250 weitere Ordner) und möchte eine Datei in alle 250 Unterverzeichnisse kopieren. Wie macht man so etwas oder geht das nur mittels eines Skripts?

Danke und Grüße
Michael
 
Moin,

ich denke, das löst man am besten mit einem Shell-Script. Liegen denn in dem einen Ordner nur diese Unterordner oder haben diese ein Namensschema? Dann kannst Du nämlich ls verwenden:
Code:
ls -1 [I]ordner[/I] | xargs -n 1 cp [I]datei[/I]

EDIT: bei der Option zu ls handelt es sich um eine 1 sprich Eins - kein kleines L. Das gleiche gilt für xargs -n

Um zu testen, ob das richtig ist, kannst Du einen Testlauf mit
Code:
ls -1 [I]ordner[/I] | xargs -n 1 echo cp [I]datei[/I]
machen.

Ich hoffe, ich konnte helfen :)
Gruß, jpv
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Macschrauber und Seiler
Hi,
danke für deine Antwort. Hat mir leider nicht geholfen und ich hab es jetzt über ein Perl Skript gelöst...

Grüße
Michael
 
Warum hat es nicht geholfen? Funktioniert doch einwandfrei.
Wenn Du damit nicht klargekommen bist, hättest Du auch eine einfache for Schleife verwenden können.
So sehr ich Perl mag, finde ich doch, dass das etwas oversized für so einen simplen Job ist.
 
Hi,

wie gesagt, hat mir leider nicht geholfen, da er bei mir nichts kopiert hat. Hab es dann mit einem Perl Skript gelöst, ist zwar zugegeben oversized. Hätte es auch gerne einfacher gelöst. Kenne mich leider mit der shell nicht wirklich gut aus, kann daher nicht beurteilen wo das Problem liegt. Hab so eine Struktur: Ordner X mit 2 Unterordner A,B. In X liegt eine Textdatei, die in A und B kopiert werden soll. Bei mir sind es aber leider nicht nur zwei (dann bräuchte ich keine automatische Lösung) sondern 253 Ordner...

Grüße Michael
 
...
wie gesagt, hat mir leider nicht geholfen, da er bei mir nichts kopiert hat. ...
Dann hast Du sehr wahrscheinlich das Kommando nicht richtig verstanden bzw. umgesetzt.
Du solltest die zu kopierende Datei in einen Ordner /Y legen. In X dürfen nur Ordner sein, in die die Datei kopiert werden soll. Dann geht:
Code:
ls -1 X | xargs -n 1 cp /Y/Datei
Wenn Deine Struktur das nicht hergibt, musst Du halt etwas kreativ sein.
Eine flexible Alternative wäre z.B. eine for-Schleife, die Du mit den passenden Werten individuell initialisieren kannst. Wie Schleifen funktionieren ist in den manpages der von Dir verwendeten Shell beschrieben. Eine weitere Alternative wäre, xargs nicht mit einem ls Kommando zu füttern sondern ein passendes find Kommando vorzuschalten.

Was mich noch interessieren würde, ist, wie Du es in Perl umgesetzt hast.
 
  • Gefällt mir
Reaktionen: Seiler
Hi,
hatte tatsächlich die Beschreibung nicht ganz verstanden, jetzt geht es... Danke dafür...
Hab ja aber nie Behauptet, dass es falsch ist, hat nur (auf Grund meines Fehlers) nicht funktioniert...;)
Den Code kann ich gerne morgen posten, hab ihn an der Arbeit. Hab es aber im wesentlichen über eine foreach -Schleife gelöst, in der ich dann das Ziel des cp Befehls verändert hab...Poste morgen mehr...

Grüße und Danke
Michael
 
Uraltes Thema, aber für mich gerade aktuell. (Und eigentlich ist die Problemstellung ja zeitlos. ;) )
Ich hab das mal nachvollzogen und bin so weit:

  • Verzeichnis x und y liegen auf einer Ebene.
  • x enthält die Verzeichnisse a,b,c
  • y enthält die Datei info.txt -> Die soll in a,b,c landen.
  • im Terminal befinde ich mich in x zur Zeit der Ausführung
  • Das Kommando lautet dann:
    Code:
    ls -1 | xargs -n 1 cp ../y/info.txt
Alles wunderbar. - So lange, bis die Verzeichnisse nicht mehr a,b,c heißen, sondern Leerzeichen enthalten. Dann nämlich, werden mittels jedes einzelnen Wortes der Dateinamen neue Dateien mit diesen Wörtern erzeugt. :(

Was kann ich dagegen tun?
 
Sollte so funktionieren:
Code:
find . -type d -exec cp -p ../y/info.txt {} \;

Edit: Möglichkeit #1 hab ich wieder rausgenommen, die hätte mit Leerzeichen im Dateinamen ebenfalls nicht funktioniert.

Edit: Mir ist doch noch eine weitere Möglichkeit eingefallen. Für den Fall, dass sich am aktuellen Ort nur Verzeichnisse und keine Dateien befinden (wenn jetzt jemand ums Eck kommt mit "Verzeichnisse sind auch nur Dateien" gibt's ein paar auf die Glocke):

Code:
ls > /tmp/,
while read line; do
 cp -p ../y/info.txt ./${i}
done < /tmp/,
rm -f /tmp/,

Sollten sich am aktuellen Ort auch reguläre Dateien befinden, muss der ls umgeschrieben werden:
Code:
ls -F | grep "/" > /tmp/,

In beiden Fällen kann statt "cp -p" auch "rsync -a" verwendet werden. Die Syntax bleibt ansonsten gleich.
 
  • Gefällt mir
Reaktionen: Macschrauber und MiBSuM
Wow! Danke!
Tatsache. Das funktioniert. Jetzt versuch ich noch zu verstehen, was das Kommando macht. (Mach ich gleich mit "info".)
Vielen Dank noch mal. :)
 
Code:
man find
ist dein bester Freund ;)
 
Ich hab
Code:
info find
benutzt. Aber das kommt wohl auf das Selbe.
Hab alles verstanden. Nur den Backslash vor dem Semikolon nicht. Wozu dient der?
 
Um das Semikolon zu escapen. find führt die Kette an Befehlen unter Umständen in einem einzelnen Kommando aus (cp -p datei1 verzeichnis1 ; cp -p datei1 verzeichnis2 ; cp -p datei1 verzeichnis3 ; ...) und somit das Semikolon als Teil des Befehls escapen muss, sonst wird es als Teil des Dateinamens interpretiert (also quasi cp -p datei1 "verzeichnis1 ;")
 
  • Gefällt mir
Reaktionen: MiBSuM
Ah, ok. Danke.
Jetzt auch unten in der Erklärung von "find" unter der Rubrik "BUGS" gefunden.
 
noch 'ne variante mit find/xargs (-print0 -> -0 beherrscht leerzeichen), überschreibschutz (cp -n) und file im aktuellen ordner.
Code:
find . -type d -mindepth 1 -print0 | xargs -0 -n 1 cp -npv ./file
 
  • Gefällt mir
Reaktionen: MiBSuM
Jetzt fehlt nur noch die Haskellvariante ..
 
dann aber parallel haskell.
 
Hallo, ich habe das oben genannte Beispiel (ls -1 | xargs -n 1 cp ../y/info.txt) eingegeben und es funktioniert auch!
Ich bräuchte die Funktion so, dass aber die Dateien nur kopiert werden, wenn die Datei vorhanden ist ( ich möchte vorhandene Dateien ersetzen).
Kann mir da jemand helfen?
Also das Gegenteil von -n bräuchte ich wahrscheinlich^^

Ich habe inzwischen die Antwort :)
find . -type f -name "info.txt" -exec cp -v ../y/info.txt {} \;
 
Zuletzt bearbeitet:
Nur der Vollständigkeit halber:

1. Aus Verzeichnisnamen ein Array erstellen:
Code:
myd=(`ls -d */`)

1.1. {Falls erwünscht Array Inhalt überprüfen:->
Array Inhalt überprüfen:
Code:
echo ${myd[*]}
}

2. Kopieren durch Anwendung der for Schleife:
Code:
for i in ${myd[*]}; do cp testdatei $i; done


Dieser Lösungsweg kann durch Schleifen und Abfragen ergänzt werden.
 
da brauchts kein array.
Code:
for d in */; do cp -npv ./file "$d"; done
wäre völlig ausreichend, solange die verzeichnistiefe 1 nicht überschritten werden muss.

und wenn du $i nicht quotest, stolperst du, wie weiter oben ja als problem benannt, wieder über leerzeichen.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: MiBSuM
Zurück
Oben Unten