Wie benenne ich Dateien beim Kopieren um?

12

Wie würde ich alle Dateien in einem Sicherungsverzeichnis in das Benutzerverzeichnis kopieren (Archivierungsstil, bei dem das Datum nicht geändert wird), während ich jede Datei umbenenne, um den zufälligen Zeichenfolgenteil aus dem Namen zu entfernen (dh -2b0fd460_1426b77b1ee_-7b8e)?

cp von:

/backup/path/data/Erp.2014.02.16_16.57.03-2b0fd460_1426b77b1ee_-7b8e.etf

zu:

/home/user/data/Erp.2014.02.16_16.57.03.etf

Jede Datei beginnt immer mit "Erp". gefolgt von der Datum-Uhrzeit-Zeichenfolge, gefolgt von der Zufallszeichenfolge und der Erweiterung ".etf". Ich möchte alle Namenselemente einschließlich des Datums- und Zeitstempels behalten. Ich möchte nur die zufällige Zeichenfolge entfernen.

Die zufällige Zeichenfolge ermöglicht mehrere Sicherungen derselben Datei. In diesem Fall habe ich jedoch nur fdupes ausgeführt und es gibt keine Duplikate. So kann ich einfach alle Dateien wiederherstellen und die zufällige Zeichenfolge entfernen.

Ich suche einen einzeiligen Bash-Befehl, um das zu tun.

Wenn das nicht funktioniert, könnte ich es in zwei oder mehr Schritten tun. Normalerweise benutze ich KRename, aber in diesem Fall muss ich es in bash machen. (Ich arbeite aus der Ferne.)

MountainX-for-Monica
quelle

Antworten:

7

paxkann das alles auf einmal tun. Du könntest es tun:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' Erp*etf /home/user/data

paxErhält die Zeiten standardmäßig, kann aber hinzufügen -pe, um alles zu erhalten (am besten als root) oder -ppum Berechtigungen beizubehalten, zB:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' -pe Erp*etf /home/user/data

Andernfalls ( paxnormalerweise nicht standardmäßig verfügbar) ist es sicherlich besser, eine Kopie zu erstellen, als a rename:

cp -a /backup/path/data/Erp*.etf /home/user/data
rename 's/-.*$/.etf/' /home/user/data/Erp*.etf

Auf diese Weise wird nicht für jede Datei ein anderer Prozess gestartet.

Graeme
quelle
1
Ich kann sehen, dass ich mich daran gewöhnen muss pax. Dies scheint ein sehr nützliches Werkzeug zu sein. Ich frage mich, warum es in mehr Distributionen nicht Standard ist ...
MountainX-for-Monica
@MountainX, Gute Frage, laut Wikipedia, paxgibt es seit 2005 in der Linux Standard Base. Außerdem ist GNU cpio, die Alternative dazu, möglicherweise das am wenigsten nützliche GNU-Tool, das es gibt.
Graeme
1
+1 für Ihre letzte Lösung und Auf diese Weise wird nicht für jede Datei ein anderer Prozess gestartet. Bei rename Fedora / Red Hat ist das anders: Ich weiß nicht, wie ich es in diesem Fall verwenden soll.
Erik
15

Sie können den cpBefehl mit der -aOption verwenden

-a, --archive
       same as -dR --preserve=all

Verwenden Sie dann eine for-Schleife, um alle Dateien beim Kopieren umzubenennen:

for file in Erp*etf; do
  cp -a $file destinationDirectory/${file%%-*}.etf
done

Bereit. Starten Sie diesen Befehl im Quellverzeichnis.

Erläuterung: Das %%-*wird abgeschnitten alle Zeichen nach dem ersten Auftreten von einem Bindestrich / Minus- und die .etfam Ende fügt wieder die Dateierweiterung.

Nun, und als One-Liner setzen Sie alles in eine Zeile. :-) So was

for file in Erp*etf; do cp -a $file destinationDirectory/${file%%-*}.etf; done
erik
quelle
1
Danke, könnten Sie bitte die Dokumentation für den %%-*Tipp zitieren ? Ich bin neugierig.
Sojuka
3

Verwenden Sie in zsh zmv. Fügen Sie dies in Ihre .zshrc:

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

Dann benutze

zcp '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

In der Bash:

zsh -c 'autoload zmv; zmv -C $0 $1' '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

Wenn Sie kein zsh haben, eine POSIX-Methode pax (dies kopiert Verzeichnisse rekursiv).

Wenn Sie sich auf einem eingeschränkten System ohne zsh und ohne pax befinden, können Sie eine Schleife verwenden:

for source in /backup/path/data/*-*.etf; do
  basename=${source##*/}
  cp "$source" "/home/user/data/${basename%-*}.${basename##*.}"
done
Gilles 'SO - hör auf böse zu sein'
quelle
1

cphat diese Fähigkeit nicht. Ich erinnere cpiomich, dass ich das kann, aber die aktuelle Manpage sagt etwas anderes aus. (Gnu) tarhat jedoch eine --transformOption:

 --transform, --xform EXPRESSION
       use sed replace EXPRESSION to transform file names

Sie hätten also eine cmdline wie:

(cd /backup/path/data; tar --create --transform 's/-.*-....//' .) | (cd /home/user/data; tar --extract)
Ricky Beam
quelle