Datei x-mal in der Befehlsshell duplizieren

22

Ich versuche, eine Videodatei x-mal über die Befehlszeile mit einer for-Schleife zu duplizieren. Ich habe es folgendermaßen versucht, aber es funktioniert nicht:

for i in {1..100}; do cp test.ogg echo "test$1.ogg"; done
Schwarz
quelle
5
Ist dein einziger Fehler nicht der, echoder nicht da sein sollte, und der, $1der sein sollte $i?
Julie Pelletier
Wenn ich das Echo entferne und nur benutze test$1.ogg, heißt es: test.ogg und test.ogg sind die gleichen Dateien , also scheint es, als würde $ 1 nicht erkannt?
Black
@EdwardBlack: Hört sich so an, als hätte ich Ihre Anforderungen falsch verstanden. Diese Lösung ist nicht geeignet.
Dienstag,
@ JuliePelletier, verdammt, es passiert mir manchmal, dass ich versehentlich schreibe, $1anstatt $i, es ist früh am Morgen, sorry ... danke. Ich werde $xin Zukunft statt$i
Black

Antworten:

25

Ihr Shell-Code weist zwei Probleme auf:

  1. Der echosollte nicht da sein.
  2. Die Variable $iist wie $1im Zieldateinamen falsch geschrieben .

Um eine Kopie einer Datei im selben Verzeichnis wie die Datei selbst zu erstellen, verwenden Sie

cp thefile thecopy

Wenn Sie dort noch etwas einfügen, z

cp thefile theotherthing thecopy

dann wird angenommen, dass Sie kopieren thefileund theotherthingin das Verzeichnis namens möchten thecopy.

In Ihrem Fall sucht es speziell nach einer Datei mit dem Namen test.oggund einer mit dem Namen echo, die in das Verzeichnis kopiert werden soll test$1.ogg.

Das $1wird höchstwahrscheinlich zu einer leeren Zeichenfolge erweitert. Aus diesem Grund erhalten Sie beim Löschen des echoBefehls "test.ogg und test.ogg sind die gleichen Dateien". Der auszuführende Befehl ist im Wesentlichen

cp test.ogg test.ogg

Dies ist wahrscheinlich ein Tippfehler.

Am Ende möchten Sie so etwas wie Folgendes:

for i in {1..100}; do cp test.ogg "test$i.ogg"; done

Oder als Alternative

i=0
while (( i++ < 100 )); do
  cp test.ogg "test$i.ogg"
done

Oder mit tee:

tee test{1..100}.ogg <test.ogg >/dev/null

Hinweis: Dies würde höchstwahrscheinlich für 100 Kopien funktionieren, aber bei Tausenden von Kopien kann der Fehler "Argumentliste zu lang" auftreten. Verwenden Sie in diesem Fall wieder eine Schleife.

Kusalananda
quelle
12

Kurz und präzise

< test.ogg tee test{1..100}.ogg

oder noch besser machen

tee test{1..100}.ogg < test.ogg >/dev/null

siehe Befehl tee Verwendung für mehr Hilfe.

Aktualisieren

Wie von @Gilles vorgeschlagen, hat using teeden Nachteil, dass keine Dateimetadaten erhalten bleiben . Um dieses Problem zu beheben, müssen Sie möglicherweise den folgenden Befehl ausführen:

cp --attributes-only --preserve Source Target
Rahul
quelle
3
Dies ist möglicherweise schneller als mehrere Aufrufe von cp(abhängig von der Dateigröße im Verhältnis zum verfügbaren Speicher), hat jedoch den Nachteil, dass keine Dateimetadaten beibehalten werden.
Gilles 'SO - hör auf, böse zu sein'
@ Gilles ohh, können wir das überwinden?
Rahul
3
Sie können cp --attributes-onlydanach laufen .
Gilles 'SO - hör auf böse zu sein'
@ Gilles Dank, aktualisiert meine Antwort gemäß Ihrer Hilfe.
Rahul
FWIW keine der anderen Antworten verwendet cp -p, um Metadaten zu erhalten.
Roaima
11
for i in {1..100}; do cp test.ogg "test_$i.ogg" ; done
Kaffeebecher
quelle
1
Variable Erweiterungen sollten angegeben werden.
Katze
1

Der folgende Befehl kopiert file.a fünfmal:

$ seq 5 | xargs -I AA cp file.a fileAA.a

Wenn Sie dd bevorzugen (nicht das gleiche wie cp!):

$ seq 5 | xargs -I AA dd if=file.a of=fileAA.a
cy8g3n
quelle
0

Sie haben beim Kopieren die Variable i nicht aufgerufen

Verwenden Sie das folgende Skript. Wie getestet hat es gut funktioniert

for i in {1..10}; do cp -rvfp test.ogg test$i.ogg ;done
Praveen Kumar BS
quelle
3
Dies ist das Gleiche wie bei zwei vorherigen Antworten und einem Kommentar, mit der Ausnahme, dass (1) in der Frage ungefähr 100 gestellt werden und in Ihrer Antwort 10 verwendet werden, (2) Sie die -rvfOptionen unnötigerweise hinzugefügt haben cpund (3) Sie Ihre Variablenerweiterung nicht angegeben haben . (Beachten Sie auch, dass es üblich ist, ein Leerzeichen zwischen Satzzeichen wie ;und dem folgenden Wort einzufügen.) Das Hinzufügen der -pOption ist nützlich, aber (4a) es wurde bereits (in Kommentaren) angesprochen, und (4b) Ihre Antwort ist es nicht hilfreich, wenn Sie nicht erklären, was Sie tun.
Scott