it-swarm.com.de

Wie kopiere ich mehrere Dateien per Platzhalter?

Ich habe einen Ordner mit einer Reihe von Dateien ABC. * (Es gibt ungefähr 100 solcher Dateien). Ich möchte sie alle in neue Dateien mit Namen duplizieren, die mit DEF beginnen. *

Also will ich

ABC.Page1
ABC.Page2
ABC.Topic12
...etc

kopiert nach

DEF.Page1
DEF.Page2
DEF.Topic12
...etc

Was ist der einfachste Weg, dies mit einem Batch-Befehl (in BASH oder ähnlichem) zu tun? Ich denke an etwas mit sed oder awk oder xargs, aber ich habe Schwierigkeiten, die Syntax herauszufinden. Ich könnte ein Python Skript schreiben), aber ich denke, es gibt wahrscheinlich eine Befehlszeilenlösung, die nicht zu kompliziert ist.

45
Octopus

Wie wäre es mit so etwas in Bash:

for file in ABC.*; do cp "$file" "${file/ABC/DEF}";done

sie können es testen, indem Sie echo vor den Befehl cp stellen:

for file in ABC.*; do echo cp "$file" "${file/ABC/DEF}";done
44
Magnus

Um dies mit einer großen Anzahl von Dateien effizient zu tun, ist es besser, zu vermeiden, dass für jede Datei ein anderer cp -Prozess gestartet wird. Eine Möglichkeit wäre, sie zu kopieren und dann mit prename umzubenennen (rename ist in Debian-basierten Distributionen standardmäßig damit verknüpft). Mit diesem und dem Linux mktemp:

tmp=$(mktemp -d --tmpdir=.)
cp ABC.* "$tmp"
prename "s:$tmp/ABC:DEF:" "$tmp/"*
rmdir "$tmp"

Aktualisieren

Eigentlich könnte pax ein besserer Weg sein, um hierher zu kommen:

pax -rws '/^ABC/DEF/' ABC.* .

Obwohl pax sowohl POSIX als auch Linux Standard Base ist, enthalten es derzeit leider nur wenige Distributionen standardmäßig.

8
Graeme

tar erledigt das sehr schnell für Sie.

PRÜFUNG

Zuerst habe ich 2 Verzeichnisse und 10 Dateien erstellt:

% mkdir test1 test2 ; cd test1
% for n in `seq 1 10` ; do touch ABC.file$n ; done
% ls

> ABC.file1   ABC.file2  ABC.file4  ABC.file6  ABC.file8
> ABC.file10  ABC.file3  ABC.file5  ABC.file7  ABC.file9

Dann habe ich sie kopiert:

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC/DEF/' -xf -
% ls ../test2

> DEF.file1   DEF.file2  DEF.file4  DEF.file6  DEF.file8
> DEF.file10  DEF.file3  DEF.file5  DEF.file7  DEF.file9

VERWANDELN

Also GNU tar akzeptiert einen sed --transform=EXPRESSION Zum Umbenennen von Dateien. Dies kann sogar nur einige der Dateien umbenennen. Zum Beispiel:

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC\(.*[0-5]\)/DEF\1/' -xf -
% ls ../test2

> ABC.file6  ABC.file8  DEF.file1   DEF.file2  DEF.file4
> ABC.file7  ABC.file9  DEF.file10  DEF.file3  DEF.file5

Das ist also ein Vorteil.

STROM

Beachten Sie auch, dass dies nur zwei tar -Prozesse sind - und dass sich dies unabhängig von der Anzahl Ihrer Dateien nicht ändert.

tar | tar

tar ist so optimiert, wie Sie es sich wünschen könnten. Dies wird niemals zu Problemargumenten oder außer Kontrolle geratenen untergeordneten Prozessen führen. Dies ist nur A> B erledigt.

ARGUMENTE

Ich verwende hier 7 verschiedene Argumente, die zwischen meinen beiden tar Prozessen kombiniert werden. Das wichtigste ist hier zuerst aufgeführt:

- Stdout/stdin - Dies informiert tar darüber, dass entweder seine Eingabe oder Ausgabe zu oder von stdin/stdout Gestreamt wird = was richtig interpretiert wird, je nachdem, ob ein Archiv erstellt oder extrahiert wird.

-c Create - Dies weist tar an, das Archiv zu erstellen. Das nächste Argument, das tar erwartet, ist ...

-f Datei - Wir geben an, dass tar mit einem file Objekt und nicht mit einem Bandgerät oder was auch immer arbeitet. Und die Datei, mit der es arbeiten wird, ist, wie oben erwähnt, stdin/stdout - mit anderen Worten, unsere |pipe.

./* Alle $ PWD/Dateien - nicht zu viel, um hier zu erklären, außer dass das Archivargument zuerst kommt, also - Dann ./*.

... und auf der anderen Seite des |pipe ...

-C Verzeichnis ändern - dies informiert tar darüber, dass es in das von mir angegebene Verzeichnis geändert werden muss, bevor eine andere Aktion ausgeführt wird, also effektiv nur cd ../test2 vor der Extraktion.

--transform='s/ed/EXPR/' - wie bereits erwähnt, erfolgte die Umbenennung. Die Dokumente geben jedoch an, dass ein beliebiger sed Ausdruck oder //flag Angenommen werden kann.

-x Extract - Nachdem tar in unser Zielverzeichnis gewechselt ist und unsere Umbenennungsanweisungen erhalten hat, weisen wir es an, alle Dateien aus dem -f - |pipe Archivdatei. Kein Geheimnis.

5
mikeserv

Wenn es Ihnen nichts ausmacht, ein weniger standardmäßiges Werkzeug zu verwenden, empfehle ich die Verwendung von mmv (Massenbewegung), die für diese Art von Aufgaben geschrieben wurde. Mit mcp (Massenkopie), das Teil der Suite ist, können Sie dies einfach tun

mcp "ABC.*" "DEF.#1"

Es ist nicht gerade einfach, Download-Pakete zu finden. Das aktuelle Debian-Paket (das Arch auch in AUR verwendet) zum Kompilieren zu Hause finden Sie hier .

4
jonny

Fügen Sie in zsh die folgenden Zeilen in Ihren .zshrc Ein:

autoload -U zmv
alias zmv='noglob zmv'
alias zcp='zmv -C'
alias zln='zmv -L'

Dann in der Befehlszeile Sie können ausführen

zcp 'ABC(.*)' 'DEF$1'

oder einfach

zcp -W ABC.* DEF.*

In einer anderen Shell, solange Sie zsh installiert haben:

zsh -c 'autoload zmv; noglob zmv -CW ABC.* DEF.*'

Sie könnten dies tun:

for i in ABC.*; do cp {ABC,DEF}."${i#*.}"; done
1
Sara Fauzia